B
    ¶ôJdR ã            B   @   s   d dl mZ d dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlZdZdd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIgBZdJdK„ ZedLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dg4ƒZd€d„ ZG d‚d„ deƒZG dƒdA„ dAeƒZG d„d&„ d&eƒZG d…d
„ d
eƒZG d†d‡„ d‡eƒZG dˆd„ deƒZG d‰d„ deƒZG dŠd„ deƒZG d‹d„ deƒZG dŒd„ deƒZG dd„ deƒZG dŽd	„ d	eƒZG dd„ deƒZG dd„ deƒZ G d‘d„ deƒZ!G d’dF„ dFeƒZ"G d“d„ deƒZ#G d”d„ deƒZ$G d•d„ deƒZ%G d–d„ deƒZ&G d—d„ deƒZ'G d˜d„ deƒZ(G d™d„ deƒZ)G dšd„ deƒZ*G d›d„ deƒZ+G dœd „ d eƒZ,G dd#„ d#eƒZ-G džd(„ d(eƒZ.G dŸd+„ d+eƒZ/G d d,„ d,eƒZ0G d¡d-„ d-eƒZ1G d¢d.„ d.eƒZ2G d£d/„ d/eƒZ3G d¤d)„ d)eƒZ4G d¥d0„ d0eƒZ5G d¦d1„ d1eƒZ6G d§d2„ d2eƒZ7G d¨d3„ d3eƒZ8G d©d4„ d4eƒZ9G dªd5„ d5eƒZ:G d«d6„ d6eƒZ;G d¬d7„ d7eƒZ<G d­d8„ d8eƒZ=G d®d;„ d;eƒZ>G d¯d<„ d<eƒZ?G d°d?„ d?eƒZ@G d±d=„ d=eƒZAG d²d>„ d>eƒZBG d³dE„ dEeƒZCG d´dG„ dGeƒZDG dµdH„ dHeƒZEd¶d·„ ZFG d¸d9„ d9eƒZGG d¹d'„ d'eGƒZHG dºdD„ dDeGƒZIG d»d@„ d@eƒZJG d¼d„ deGƒZKG d½d!„ d!eƒZLG d¾d„ deƒZMG d¿d:„ d:eƒZNG dÀd*„ d*eƒZOG dÁdI„ dIeƒZPG dÂdC„ dCeƒZQG dÃd$„ d$eƒZRG dÄd%„ d%eƒZSG dÅdB„ dBeƒZTG dÆd„ deƒZUG dÇd"„ d"eƒZVG dÈdÉ„ dÉeƒZWdS )Êé    )ÚFeatureLibError)ÚFeatureLibLocation)ÚgetEncoding)ÚbyteordÚtobytes)ÚOrderedDictNz    Ú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ÚConditionsetStatementÚ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             C   s(   | d krdS dd  dd„ | D ƒ¡ S d S )Nz<device NULL>z<device %s>z, c             s   s   | ]}d | V  qdS )z%d %dN© )Ú.0ÚtrJ   rJ   úF/var/www/html/venv/lib/python3.7/site-packages/fontTools/feaLib/ast.pyú	<genexpr>T   s    z!deviceToString.<locals>.<genexpr>)Újoin)ÚdevicerJ   rJ   rM   ÚdeviceToStringP   s    rQ   ÚanchorZ	anchordefZanonZ	anonymousZbyZcontourZcursiverP   ÚenumÚ	enumerateZexcludedfltZexclude_dfltÚfeatureÚfromÚignoreZignorebaseglyphsZignoreligaturesZignoremarksÚincludeZincludedfltZinclude_dfltÚlanguageZlanguagesystemÚlookupZ
lookupflagÚmarkZmarkattachmenttypeZ	markclassZnameidÚnullÚ
parametersÚposÚpositionÚrequiredZrighttoleftZ
reversesubZrsubÚscriptÚsubÚ
substituteZsubtableÚtableZusemarkfilteringsetZuseextensionZvaluerecorddefÚbaseZgdefÚheadZhheaÚnameZvheaZvmtxc             C   s`   t | dƒr|  ¡ S t| tƒrDt| ƒdkrDt| d ƒd t| d ƒ S |  ¡ tkrXd|  S | S d S )NÚasFeaé   r   z - é   ú\)Úhasattrrh   Ú
isinstanceÚtupleÚlenÚlowerÚfea_keywords)ÚgrJ   rJ   rM   rh   ‘   s    
rh   c               @   s4   e Zd ZdZddd„Zdd„ Zddd	„Zd
d„ ZdS )r   z8A base class representing "something" in a feature file.Nc             C   s    |rt |tƒst|Ž }|| _d S )N)rm   r   Úlocation)Úselfrs   rJ   rJ   rM   Ú__init__Ÿ   s    zElement.__init__c             C   s   d S )NrJ   )rt   ÚbuilderrJ   rJ   rM   Úbuild¥   s    zElement.buildÚ c             C   s   t ‚dS )zÀReturns 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.N)ÚNotImplementedError)rt   ÚindentrJ   rJ   rM   rh   ¨   s    zElement.asFeac             C   s   |   ¡ S )N)rh   )rt   rJ   rJ   rM   Ú__str__®   s    zElement.__str__)N)rx   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ru   rw   rh   r{   rJ   rJ   rJ   rM   r   œ   s
   

c               @   s   e Zd ZdS )rA   N)r|   r}   r~   rJ   rJ   rJ   rM   rA   ²   s   c               @   s   e Zd ZdS )r&   N)r|   r}   r~   rJ   rJ   rJ   rM   r&   ¶   s   c                   s,   e Zd ZdZd‡ fdd„	Zd	dd„Z‡  ZS )
r
   zA comment in a feature file.Nc                s   t t| ƒ |¡ || _d S )N)Úsuperr
   ru   Útext)rt   r   rs   )Ú	__class__rJ   rM   ru   ½   s    zComment.__init__rx   c             C   s   | j S )N)r   )rt   rz   rJ   rJ   rM   rh   Â   s    zComment.asFea)N)rx   )r|   r}   r~   r   ru   rh   Ú__classcell__rJ   rJ   )r‚   rM   r
   º   s   c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )Ú	NullGlyphz5The NULL glyph, used in glyph deletion substitutions.Nc             C   s   t  | |¡ d S )N)r&   ru   )rt   rs   rJ   rJ   rM   ru   É   s    zNullGlyph.__init__c             C   s   dS )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.rJ   rJ   )rt   rJ   rJ   rM   ÚglyphSetÍ   s    zNullGlyph.glyphSetrx   c             C   s   dS )NÚNULLrJ   )rt   rz   rJ   rJ   rM   rh   Ñ   s    zNullGlyph.asFea)N)rx   )r|   r}   r~   r   ru   r…   rh   rJ   rJ   rJ   rM   r„   Æ   s   
r„   c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z)A single glyph name, such as ``cedilla``.Nc             C   s   t  | |¡ || _d S )N)r&   ru   Úglyph)rt   r‡   rs   rJ   rJ   rM   ru   Ø   s    zGlyphName.__init__c             C   s   | j fS )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)r‡   )rt   rJ   rJ   rM   r…   Ý   s    zGlyphName.glyphSetrx   c             C   s
   t | jƒS )N)rh   r‡   )rt   rz   rJ   rJ   rM   rh   á   s    zGlyphName.asFea)N)rx   )r|   r}   r~   r   ru   r…   rh   rJ   rJ   rJ   rM   r   Õ   s   
c               @   sT   e Zd ZdZddd„Zdd„ Zddd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )r   z1A glyph class, such as ``[acute cedilla grave]``.Nc             C   s.   t  | |¡ |d k	r|ng | _g | _d| _d S )Nr   )r&   ru   ÚglyphsÚoriginalÚcurr)rt   rˆ   rs   rJ   rJ   rM   ru   è   s    zGlyphClass.__init__c             C   s
   t | jƒS )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rn   rˆ   )rt   rJ   rJ   rM   r…   ï   s    zGlyphClass.glyphSetrx   c             C   sv   t | jƒrX| jt | jƒk r>| j | j| jd … ¡ t | jƒ| _dd tt| jƒ¡ d S dd tt| jƒ¡ d S d S )Nú[ú ú])ro   r‰   rŠ   rˆ   ÚextendrO   Úmaprh   )rt   rz   rJ   rJ   rM   rh   ó   s    
zGlyphClass.asFeac             C   s   | j  |¡ dS )z6Add a list of :class:`GlyphName` objects to the class.N)rˆ   rŽ   )rt   rˆ   rJ   rJ   rM   rŽ   ü   s    zGlyphClass.extendc             C   s   | j  |¡ dS )z4Add a single :class:`GlyphName` object to the class.N)rˆ   Úappend)rt   r‡   rJ   rJ   rM   r      s    zGlyphClass.appendc             C   sT   | 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Š   ro   rˆ   r‰   rŽ   r   )rt   ÚstartÚendrˆ   rJ   rJ   rM   Ú	add_range  s
    zGlyphClass.add_rangec             C   s`   | j t| jƒk r(| j | j| j d… ¡ | j d |¡d |¡f¡ | j |¡ t| jƒ| _ dS )z¶Add 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Š   ro   rˆ   r‰   rŽ   r   Úformat)rt   r‘   r’   rˆ   rJ   rJ   rM   Úadd_cid_range  s
    zGlyphClass.add_cid_rangec             C   sT   | 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Š   ro   rˆ   r‰   rŽ   r   r…   )rt   ÚgcrJ   rJ   rM   Ú	add_class  s
    zGlyphClass.add_class)NN)rx   )r|   r}   r~   r   ru   r…   rh   rŽ   r   r“   r•   r—   rJ   rJ   rJ   rM   r   å   s   

	
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   zyA glyph class name, such as ``@FRENCH_MARKS``. This must be instantiated
    with a :class:`GlyphClassDefinition` object.Nc             C   s$   t  | |¡ t|tƒst‚|| _d S )N)r&   ru   rm   r   ÚAssertionErrorÚ
glyphclass)rt   r™   rs   rJ   rJ   rM   ru   '  s    zGlyphClassName.__init__c             C   s   t | j ¡ ƒS )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rn   r™   r…   )rt   rJ   rJ   rM   r…   ,  s    zGlyphClassName.glyphSetrx   c             C   s   d| j j S )Nú@)r™   rg   )rt   rz   rJ   rJ   rM   rh   0  s    zGlyphClassName.asFea)N)rx   )r|   r}   r~   r   ru   r…   rh   rJ   rJ   rJ   rM   r   #  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   zˆA mark class name, such as ``@FRENCH_MARKS`` defined with ``markClass``.
    This must be instantiated with a :class:`MarkClass` object.Nc             C   s$   t  | |¡ t|tƒst‚|| _d S )N)r&   ru   rm   r   r˜   Ú	markClass)rt   r›   rs   rJ   rJ   rM   ru   8  s    zMarkClassName.__init__c             C   s
   | j  ¡ S )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)r›   r…   )rt   rJ   rJ   rM   r…   =  s    zMarkClassName.glyphSetrx   c             C   s   d| j j S )Nrš   )r›   rg   )rt   rz   rJ   rJ   rM   rh   A  s    zMarkClassName.asFea)N)rx   )r|   r}   r~   r   ru   r…   rh   rJ   rJ   rJ   rM   r   4  s   
c               @   s$   e Zd ZdZddd„Zd	dd„ZdS )
r   zAn anonymous data block.Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   ÚtagÚcontent)rt   rœ   r   rs   rJ   rJ   rM   ru   H  s    zAnonymousBlock.__init__rx   c             C   s*   d  | j¡}|| j7 }|d  | j¡7 }|S )Nzanon {} {{
z}} {};

)r”   rœ   r   )rt   rz   ÚresrJ   rJ   rM   rh   M  s    
zAnonymousBlock.asFea)N)rx   )r|   r}   r~   r   ru   rh   rJ   rJ   rJ   rM   r   E  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z,A block of statements: feature, lookup, etc.Nc             C   s   t  | |¡ g | _d S )N)rA   ru   Ú
statements)rt   rs   rJ   rJ   rM   ru   W  s    zBlock.__init__c             C   s   x| j D ]}| |¡ qW dS )z¯When handed a 'builder' object of comparable interface to
        :class:`fontTools.feaLib.builder`, walks the statements in this
        block, calling the builder callbacks.N)rŸ   rw   )rt   rv   ÚsrJ   rJ   rM   rw   [  s    zBlock.buildrx   c                s.   ˆ t 7 ‰ ˆ dˆ   ‡ fdd„| jD ƒ¡ d S )NÚ
c                s   g | ]}|j ˆ d ‘qS ))rz   )rh   )rK   r    )rz   rJ   rM   ú
<listcomp>f  s    zBlock.asFea.<locals>.<listcomp>)ÚSHIFTrO   rŸ   )rt   rz   rJ   )rz   rM   rh   b  s    zBlock.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   T  s   
c               @   s"   e Zd ZdZdd„ Zddd„ZdS )	r	   zpThe top-level element of the syntax tree, containing the whole feature
    file in its ``statements`` attribute.c             C   s   t j| d d i | _d S )N)rs   )r   ru   ZmarkClasses)rt   rJ   rJ   rM   ru   o  s    zFeatureFile.__init__rx   c                s   d  ‡ fdd„| jD ƒ¡S )Nr¡   c             3   s   | ]}|j ˆ d V  qdS ))rz   N)rh   )rK   r    )rz   rJ   rM   rN   t  s    z$FeatureFile.asFea.<locals>.<genexpr>)rO   rŸ   )rt   rz   rJ   )rz   rM   rh   s  s    zFeatureFile.asFeaN)rx   )r|   r}   r~   r   ru   rh   rJ   rJ   rJ   rM   r	   k  s   c               @   s,   e Zd ZdZddd„Zdd„ Zdd	d
„ZdS )r   zA named feature block.FNc             C   s   t  | |¡ || | _| _d S )N)r   ru   rg   Úuse_extension)rt   rg   r¤   rs   rJ   rJ   rM   ru   z  s    zFeatureBlock.__init__c             C   sd   |  | j| j¡ |j}i |_t | |¡ x(|j ¡ D ]\}}| |g ¡ |¡ q4W ||_| 	¡  dS )z‹Call the ``start_feature`` callback on the builder object, visit
        all the statements in this feature, and then call ``end_feature``.N)
Ústart_featurers   rg   Ú	features_r   rw   ÚitemsÚ
setdefaultrŽ   Úend_feature)rt   rv   ÚfeaturesÚkeyÚvaluerJ   rJ   rM   rw   ~  s    zFeatureBlock.buildrx   c             C   sT   |d| j  ¡   }| jr |d7 }|d7 }|tj| |d7 }||d| j  ¡   7 }|S )Nzfeature %s zuseExtension z{
)rz   z} %s;
)rg   Ústripr¤   r   rh   )rt   rz   rž   rJ   rJ   rM   rh     s    zFeatureBlock.asFea)FN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   w  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   zYA block inside another block, for example when found inside a
    ``cvParameters`` block.Nc             C   s   t  | |¡ || _|| _d S )N)r   ru   rœ   Ú
block_name)rt   rœ   r®   rs   rJ   rJ   rM   ru   ›  s    zNestedBlock.__init__c             C   s&   t  | |¡ | jdkr"| | j¡ d S )NÚParamUILabelNameID)r   rw   r®   Zadd_to_cv_num_named_paramsrœ   )rt   rv   rJ   rJ   rM   rw      s    
zNestedBlock.buildrx   c             C   s2   d  || j¡}|tj| |d7 }|d  |¡7 }|S )Nz{}{} {{
)rz   z{}}};
)r”   r®   r   rh   )rt   rz   rž   rJ   rJ   rM   rh   ¥  s    zNestedBlock.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   —  s   
c               @   s,   e Zd ZdZddd„Zdd„ Zdd	d
„ZdS )r   z*A named lookup, containing ``statements``.FNc             C   s   t  | |¡ || | _| _d S )N)r   ru   rg   r¤   )rt   rg   r¤   rs   rJ   rJ   rM   ru   ¯  s    zLookupBlock.__init__c             C   s(   |  | j| j¡ t | |¡ | ¡  d S )N)Zstart_lookup_blockrs   rg   r   rw   Zend_lookup_block)rt   rv   rJ   rJ   rM   rw   ³  s    zLookupBlock.buildrx   c             C   sJ   d  | j¡}| jr|d7 }|d7 }|tj| |d7 }|d  || j¡7 }|S )Nz
lookup {} zuseExtension z{
)rz   z	{}}} {};
)r”   rg   r¤   r   rh   )rt   rz   rž   rJ   rJ   rM   rh   ¹  s    zLookupBlock.asFea)FN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   ¬  s   
c                   s,   e Zd ZdZddd„Zd	‡ fdd„	Z‡  ZS )
rF   zA ``table ... { }`` block.Nc             C   s   t  | |¡ || _d S )N)r   ru   rg   )rt   rg   rs   rJ   rJ   rM   ru   Æ  s    zTableBlock.__init__rx   c                s>   d  | j ¡ ¡}|tt| ƒj|d7 }|d  | j ¡ ¡7 }|S )Nztable {} {{
)rz   z}} {};
)r”   rg   r­   r€   rF   rh   )rt   rz   rž   )r‚   rJ   rM   rh   Ê  s    zTableBlock.asFea)N)rx   )r|   r}   r~   r   ru   rh   rƒ   rJ   rJ   )r‚   rM   rF   Ã  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z!Example: ``@UPPERCASE = [A-Z];``.Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   rg   rˆ   )rt   rg   rˆ   rs   rJ   rJ   rM   ru   Ô  s    zGlyphClassDefinition.__init__c             C   s   t | j ¡ ƒS )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rn   rˆ   r…   )rt   rJ   rJ   rM   r…   Ù  s    zGlyphClassDefinition.glyphSetrx   c             C   s   d| j  d | j ¡  d S )Nrš   z = ú;)rg   rˆ   rh   )rt   rz   rJ   rJ   rM   rh   Ý  s    zGlyphClassDefinition.asFea)N)rx   )r|   r}   r~   r   ru   r…   rh   rJ   rJ   rJ   rM   r   Ñ  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z¡Example: ``GlyphClassDef @UPPERCASE, [B], [C], [D];``. The parameters
    must be either :class:`GlyphClass` or :class:`GlyphClassName` objects, or
    ``None``.Nc             C   s*   t  | |¡ || | _| _|| _|| _d S )N)rA   ru   Ú
baseGlyphsÚ
markGlyphsÚligatureGlyphsÚcomponentGlyphs)rt   r±   r²   r³   r´   rs   rJ   rJ   rM   ru   æ  s    zGlyphClassDefStatement.__init__c             C   sp   | j r| j  ¡ ntƒ }| jr&| j ¡ ntƒ }| jr<| j ¡ ntƒ }| jrR| j ¡ ntƒ }| | j||||¡ dS )z3Calls the builder's ``add_glyphClassDef`` callback.N)r±   r…   rn   r³   r²   r´   Zadd_glyphClassDefrs   )rt   rv   re   Zligar[   ÚcomprJ   rJ   rM   rw   î  s
    zGlyphClassDefStatement.buildrx   c             C   sP   d  | jr| j ¡ nd| jr&| j ¡ nd| jr8| j ¡ nd| jrJ| j ¡ nd¡S )NzGlyphClassDef {}, {}, {}, {};rx   )r”   r±   rh   r³   r²   r´   )rt   rz   rJ   rJ   rM   rh   ö  s
    zGlyphClassDefStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   á  s   
c               @   s2   e Zd ZdZdd„ Zdd„ Zdd„ Zd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             C   s   || _ g | _tƒ | _d S )N)rg   Údefinitionsr   rˆ   )rt   rg   rJ   rJ   rM   ru     s    zMarkClass.__init__c             C   s|   t |tƒst‚| j |¡ x\| ¡ D ]P}|| jkrj| j| j}|dkrLd}n
d|› }td||f |jƒ‚|| j|< q$W dS )z@Add a :class:`MarkClassDefinition` statement to this mark class.Nrx   z at zGlyph %s already defined%s)	rm   r   r˜   r¶   r   r…   rˆ   rs   r   )rt   Z
definitionr‡   ZotherLocr’   rJ   rJ   rM   ÚaddDefinition  s    

zMarkClass.addDefinitionc             C   s   t | j ¡ ƒS )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rn   rˆ   Úkeys)rt   rJ   rJ   rM   r…   #  s    zMarkClass.glyphSetrx   c             C   s   d  dd„ | jD ƒ¡}|S )Nr¡   c             s   s   | ]}|  ¡ V  qd S )N)rh   )rK   ÚdrJ   rJ   rM   rN   (  s    z"MarkClass.asFea.<locals>.<genexpr>)rO   r¶   )rt   rz   rž   rJ   rJ   rM   rh   '  s    zMarkClass.asFeaN)rx   )r|   r}   r~   r   ru   r·   r…   rh   rJ   rJ   rJ   rM   r   ÿ  s
   c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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             C   sL   t  | |¡ t|tƒst‚t|tƒr.t|tƒs2t‚|||  | _| _| _	d S )N)
rA   ru   rm   r   r˜   r   r&   r›   rR   rˆ   )rt   r›   rR   rˆ   rs   rJ   rJ   rM   ru   C  s    zMarkClassDefinition.__init__c             C   s
   | j  ¡ S )zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rˆ   r…   )rt   rJ   rJ   rM   r…   I  s    zMarkClassDefinition.glyphSetrx   c             C   s   d  | j ¡ | j ¡ | jj¡S )NzmarkClass {} {} @{};)r”   rˆ   rh   rR   r›   rg   )rt   rz   rJ   rJ   rM   rh   M  s    zMarkClassDefinition.asFea)N)rx   )r|   r}   r~   r   ru   r…   rh   rJ   rJ   rJ   rM   r   ,  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   zºA ``sub ... from ...`` statement.

    ``prefix``, ``glyph``, ``suffix`` and ``replacement`` should be lists of
    `glyph-containing objects`_. ``glyph`` should be a `one element list`.Nc             C   s,   t  | |¡ |||  | _| _| _|| _d S )N)rA   ru   Úprefixr‡   ÚsuffixÚreplacement)rt   rº   r‡   r»   r¼   rs   rJ   rJ   rM   ru   Y  s    z AlternateSubstStatement.__init__c             C   sl   | j  ¡ }t|ƒdkst|ƒ‚t|ƒd }dd„ | jD ƒ}dd„ | jD ƒ}| j ¡ }| | j	||||¡ dS )z5Calls the builder's ``add_alternate_subst`` callback.rj   r   c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   ÚprJ   rJ   rM   r¢   c  s    z1AlternateSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   d  s    N)
r‡   r…   ro   r˜   Úlistrº   r»   r¼   Zadd_alternate_substrs   )rt   rv   r‡   rº   r»   r¼   rJ   rJ   rM   rw   ^  s    

zAlternateSubstStatement.buildrx   c             C   s¤   d}t | jƒst | jƒrtt | jƒr<|d tt| jƒ¡d 7 }|t| jƒd 7 }t | jƒr‚|dd tt| jƒ¡ 7 }n|t| jƒ7 }|d7 }|t| jƒ7 }|d7 }|S )Nzsub rŒ   ú'z from r°   )ro   rº   r»   rO   r   rh   r‡   r¼   )rt   rz   rž   rJ   rJ   rM   rh   h  s    

zAlternateSubstStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   S  s   

c               @   s$   e Zd ZdZddd„Zd	dd„ZdS )
r   z¬An ``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             C   s:   t  | |¡ || _|||  | _| _| _|| | _| _d S )N)r&   ru   rg   ÚxÚyÚcontourpointÚxDeviceTableÚyDeviceTable)rt   rÀ   rÁ   rg   rÂ   rÃ   rÄ   rs   rJ   rJ   rM   ru     s    
zAnchor.__init__rx   c             C   s€   | j d k	rd | j ¡S d | j| j¡}| jr<|d | j¡7 }| jsH| jrt|d7 }|t| jƒ7 }|d7 }|t| jƒ7 }|d7 }|S )Nz<anchor {}>z<anchor {} {}z contourpoint {}rŒ   ú>)rg   r”   rÀ   rÁ   rÂ   rÃ   rÄ   rQ   )rt   rz   rž   rJ   rJ   rM   rh   Ž  s    
zAnchor.asFea)NNNNN)rx   )r|   r}   r~   r   ru   rh   rJ   rJ   rJ   rM   r   x  s       
c               @   s$   e Zd ZdZddd„Zd	dd„ZdS )
r   zCA named anchor definition. (2.e.viii). ``name`` should be a string.Nc             C   s,   t  | |¡ ||||f\| _| _| _| _d S )N)rA   ru   rg   rÀ   rÁ   rÂ   )rt   rg   rÀ   rÁ   rÂ   rs   rJ   rJ   rM   ru      s    zAnchorDefinition.__init__rx   c             C   s:   d  | j| j¡}| jr&|d  | j¡7 }|d  | j¡7 }|S )NzanchorDef {} {}z contourpoint {}z {};)r”   rÀ   rÁ   rÂ   rg   )rt   rz   rž   rJ   rJ   rM   rh   ¤  s
    zAnchorDefinition.asFea)NN)rx   )r|   r}   r~   r   ru   rh   rJ   rJ   rJ   rM   r     s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z&A ``GDEF`` table ``Attach`` statement.Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   rˆ   ÚcontourPoints)rt   rˆ   rÆ   rs   rJ   rJ   rM   ru   ¯  s    zAttachStatement.__init__c             C   s    | j  ¡ }| | j|| j¡ dS )z3Calls the builder's ``add_attach_points`` callback.N)rˆ   r…   Zadd_attach_pointsrs   rÆ   )rt   rv   rˆ   rJ   rJ   rM   rw   ´  s    
zAttachStatement.buildrx   c             C   s$   d  | j ¡ d dd„ | jD ƒ¡¡S )NzAttach {} {};rŒ   c             s   s   | ]}t |ƒV  qd S )N)Ústr)rK   ÚcrJ   rJ   rM   rN   »  s    z(AttachStatement.asFea.<locals>.<genexpr>)r”   rˆ   rh   rO   rÆ   )rt   rz   rJ   rJ   rM   rh   ¹  s    zAttachStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   ¬  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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          	   C   s~   t  | |¡ |||  | _| _| _t|ƒ| _xLt|ƒD ]@\}}|r6ydd„ |D ƒ W q6 tk
rt   |g| j|< Y q6X q6W d S )Nc             s   s   | ]
}|V  qd S )NrJ   )rK   Ú_rJ   rJ   rM   rN   Ô  s    z4ChainContextPosStatement.__init__.<locals>.<genexpr>)	rA   ru   rº   rˆ   r»   r¾   ÚlookupsrT   Ú	TypeError)rt   rº   rˆ   r»   rÊ   rs   ÚirZ   rJ   rJ   rM   ru   Í  s    
z!ChainContextPosStatement.__init__c             C   sJ   dd„ | j D ƒ}dd„ | jD ƒ}dd„ | jD ƒ}| | j|||| j¡ dS )z7Calls the builder's ``add_chain_context_pos`` callback.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   Ú  s    z2ChainContextPosStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   rr   rJ   rJ   rM   r¢   Û  s    c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   Ü  s    N)rº   rˆ   r»   Úadd_chain_context_posrs   rÊ   )rt   rv   rº   rˆ   r»   rJ   rJ   rM   rw   Ø  s
    zChainContextPosStatement.buildrx   c             C   s
  d}t | jƒs,t | jƒs,tdd„ | jD ƒƒrèt | jƒrT|d dd„ | jD ƒ¡d 7 }xlt| jƒD ]^\}}|| ¡ d 7 }| j| r¤x | j| D ]}|d|j	 7 }qŽW |t | jƒd	 k r`|d7 }q`W t | jƒrþ|dd t
t| jƒ¡ 7 }n|d t
t| jƒ¡7 }|d
7 }|S )Nzpos c             S   s   g | ]}|d k	‘qS )NrJ   )rK   rÀ   rJ   rJ   rM   r¢   æ  s    z2ChainContextPosStatement.asFea.<locals>.<listcomp>rŒ   c             s   s   | ]}|  ¡ V  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   é  s    z1ChainContextPosStatement.asFea.<locals>.<genexpr>r¿   z lookup rj   r°   )ro   rº   r»   ÚanyrÊ   rO   rT   rˆ   rh   rg   r   r‡   )rt   rz   rž   rÌ   rr   ÚlurJ   rJ   rM   rh   á  s$    




zChainContextPosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   ¿  s   
	c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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          	   C   s~   t  | |¡ |||  | _| _| _t|ƒ| _xLt|ƒD ]@\}}|r6ydd„ |D ƒ W q6 tk
rt   |g| j|< Y q6X q6W d S )Nc             s   s   | ]
}|V  qd S )NrJ   )rK   rÉ   rJ   rJ   rM   rN     s    z6ChainContextSubstStatement.__init__.<locals>.<genexpr>)	rA   ru   rº   rˆ   r»   r¾   rÊ   rT   rË   )rt   rº   rˆ   r»   rÊ   rs   rÌ   rZ   rJ   rJ   rM   ru     s    
z#ChainContextSubstStatement.__init__c             C   sJ   dd„ | j D ƒ}dd„ | jD ƒ}dd„ | jD ƒ}| | j|||| j¡ dS )z9Calls the builder's ``add_chain_context_subst`` callback.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢     s    z4ChainContextSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   rr   rJ   rJ   rM   r¢     s    c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢     s    N)rº   rˆ   r»   Úadd_chain_context_substrs   rÊ   )rt   rv   rº   rˆ   r»   rJ   rJ   rM   rw     s
    z ChainContextSubstStatement.buildrx   c             C   s
  d}t | jƒs,t | jƒs,tdd„ | jD ƒƒrèt | jƒrT|d dd„ | jD ƒ¡d 7 }xlt| jƒD ]^\}}|| ¡ d 7 }| j| r¤x | j| D ]}|d|j	 7 }qŽW |t | jƒd	 k r`|d7 }q`W t | jƒrþ|dd t
t| jƒ¡ 7 }n|d t
t| jƒ¡7 }|d
7 }|S )Nzsub c             S   s   g | ]}|d k	‘qS )NrJ   )rK   rÀ   rJ   rJ   rM   r¢      s    z4ChainContextSubstStatement.asFea.<locals>.<listcomp>rŒ   c             s   s   | ]}|  ¡ V  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   #  s    z3ChainContextSubstStatement.asFea.<locals>.<genexpr>r¿   z lookup rj   r°   )ro   rº   r»   rÎ   rÊ   rO   rT   rˆ   rh   rg   r   r‡   )rt   rz   rž   rÌ   rr   rÏ   rJ   rJ   rM   rh     s$    




z ChainContextSubstStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r    ù  s   
	c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r#   znA cursive positioning statement. Entry and exit anchors can either
    be :class:`Anchor` objects or ``None``.Nc             C   s$   t  | |¡ || _|| | _| _d S )N)rA   ru   r™   ÚentryAnchorÚ
exitAnchor)rt   r™   rÑ   rÒ   rs   rJ   rJ   rM   ru   7  s    zCursivePosStatement.__init__c             C   s    |  | j| j ¡ | j| j¡ dS )z8Calls the builder object's ``add_cursive_pos`` callback.N)Zadd_cursive_posrs   r™   r…   rÑ   rÒ   )rt   rv   rJ   rJ   rM   rw   <  s    zCursivePosStatement.buildrx   c             C   s<   | j r| j  ¡ nd}| jr$| j ¡ nd}d | j ¡ ||¡S )Nz<anchor NULL>zpos cursive {} {} {};)rÑ   rh   rÒ   r”   r™   )rt   rz   ÚentryÚexitrJ   rJ   rM   rh   B  s    zCursivePosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r#   3  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r(   zExample: ``feature salt;``Nc             C   s   t  | |¡ || | _| _d S )N)rA   ru   rs   ÚfeatureName)rt   rÕ   rs   rJ   rJ   rM   ru   K  s    z"FeatureReferenceStatement.__init__c             C   s   |  | j| j¡ dS )z>Calls the builder object's ``add_feature_reference`` callback.N)Zadd_feature_referencers   rÕ   )rt   rv   rJ   rJ   rM   rw   O  s    zFeatureReferenceStatement.buildrx   c             C   s   d  | j¡S )Nzfeature {};)r”   rÕ   )rt   rz   rJ   rJ   rM   rh   S  s    zFeatureReferenceStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r(   H  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r+   zøAn ``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             C   s   t  | |¡ || _d S )N)rA   ru   ÚchainContexts)rt   rÖ   rs   rJ   rJ   rM   ru   ^  s    zIgnorePosStatement.__init__c             C   sX   xR| j D ]H\}}}dd„ |D ƒ}dd„ |D ƒ}dd„ |D ƒ}| | j|||g ¡ qW dS )z[Calls the builder object's ``add_chain_context_pos`` callback on each
        rule context.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   f  s    z,IgnorePosStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   rr   rJ   rJ   rM   r¢   g  s    c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   h  s    N)rÖ   rÍ   rs   )rt   rv   rº   rˆ   r»   rJ   rJ   rM   rw   b  s
    zIgnorePosStatement.buildrx   c             C   s¸   g }x | j D ]–\}}}d}t|ƒs*t|ƒr„t|ƒrJ|d tt|ƒ¡d 7 }|d dd„ |D ƒ¡7 }t|ƒr˜|dd tt|ƒ¡ 7 }n|d tt|ƒ¡7 }| |¡ qW dd |¡ d S )Nrx   rŒ   c             s   s   | ]}|  ¡ d  V  qdS )r¿   N)rh   )rK   rr   rJ   rJ   rM   rN   r  s    z+IgnorePosStatement.asFea.<locals>.<genexpr>zignore pos z, r°   )rÖ   ro   rO   r   rh   r   )rt   rz   Úcontextsrº   rˆ   r»   rž   rJ   rJ   rM   rh   k  s    zIgnorePosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r+   W  s   
	c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r,   zøAn ``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             C   s   t  | |¡ || _d S )N)rA   ru   rÖ   )rt   rÖ   rs   rJ   rJ   rM   ru   ‚  s    zIgnoreSubstStatement.__init__c             C   sX   xR| j D ]H\}}}dd„ |D ƒ}dd„ |D ƒ}dd„ |D ƒ}| | j|||g ¡ qW dS )z]Calls the builder object's ``add_chain_context_subst`` callback on
        each rule context.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   Š  s    z.IgnoreSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   rr   rJ   rJ   rM   r¢   ‹  s    c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   Œ  s    N)rÖ   rÐ   rs   )rt   rv   rº   rˆ   r»   rJ   rJ   rM   rw   †  s
    zIgnoreSubstStatement.buildrx   c             C   s¸   g }x | j D ]–\}}}d}t|ƒs*t|ƒr„t|ƒrJ|d tt|ƒ¡d 7 }|d dd„ |D ƒ¡7 }t|ƒr˜|dd tt|ƒ¡ 7 }n|d tt|ƒ¡7 }| |¡ qW dd |¡ d S )Nrx   rŒ   c             s   s   | ]}|  ¡ d  V  qdS )r¿   N)rh   )rK   rr   rJ   rJ   rM   rN   –  s    z-IgnoreSubstStatement.asFea.<locals>.<genexpr>zignore sub z, r°   )rÖ   ro   rO   r   rh   r   )rt   rz   r×   rº   rˆ   r»   rž   rJ   rJ   rM   rh     s    zIgnoreSubstStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r,   {  s   
	c                   s4   e Zd ZdZd
‡ fdd„	Zdd„ Zddd	„Z‡  ZS )r-   zAn ``include()`` statement.Nc                s   t t| ƒ |¡ || _d S )N)r€   r-   ru   Úfilename)rt   rØ   rs   )r‚   rJ   rM   ru   ¢  s    zIncludeStatement.__init__c             C   s   t d| jƒ‚d S )NzqBuilding an include statement is not implemented yet. Instead, use Parser(..., followIncludes=True) for building.)r   rs   )rt   rJ   rJ   rM   rw   ¦  s    zIncludeStatement.buildrx   c             C   s   |d| j   S )Nzinclude(%s);)rØ   )rt   rz   rJ   rJ   rM   rh   ®  s    zIncludeStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rƒ   rJ   rJ   )r‚   rM   r-   Ÿ  s   c               @   s,   e Zd ZdZddd„Zdd„ Zdd
d„ZdS )r.   z*A ``language`` statement within a feature.TFNc             C   s2   t  | |¡ t|ƒdkst‚|| _|| _|| _d S )Né   )rA   ru   ro   r˜   rY   Úinclude_defaultr`   )rt   rY   rÚ   r`   rs   rJ   rJ   rM   ru   µ  s
    zLanguageStatement.__init__c             C   s   |j | j| j| j| jd dS )z4Call the builder object's ``set_language`` callback.)rs   rY   rÚ   r`   N)Zset_languagers   rY   rÚ   r`   )rt   rv   rJ   rJ   rM   rw   ¼  s
    zLanguageStatement.buildrx   c             C   s8   d  | j ¡ ¡}| js|d7 }| jr,|d7 }|d7 }|S )Nzlanguage {}z exclude_dfltz	 requiredr°   )r”   rY   r­   rÚ   r`   )rt   rz   rž   rJ   rJ   rM   rh   Å  s    zLanguageStatement.asFea)TFN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r.   ²  s   
	c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r/   z)A top-level ``languagesystem`` statement.Nc             C   s   t  | |¡ || | _| _d S )N)rA   ru   ra   rY   )rt   ra   rY   rs   rJ   rJ   rM   ru   Ò  s    z LanguageSystemStatement.__init__c             C   s   |  | j| j| j¡ dS )z<Calls the builder object's ``add_language_system`` callback.N)Zadd_language_systemrs   ra   rY   )rt   rv   rJ   rJ   rM   rw   Ö  s    zLanguageSystemStatement.buildrx   c             C   s   d  | j| j ¡ ¡S )Nzlanguagesystem {} {};)r”   ra   rY   r­   )rt   rz   rJ   rJ   rM   rh   Ú  s    zLanguageSystemStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r/   Ï  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r)   zŒA ``head`` table ``FontRevision`` statement. ``revision`` should be a
    number, and will be formatted to three significant decimal places.Nc             C   s   t  | |¡ || _d S )N)rA   ru   Úrevision)rt   rÛ   rs   rJ   rJ   rM   ru   â  s    zFontRevisionStatement.__init__c             C   s   |  | j| j¡ d S )N)Zset_font_revisionrs   rÛ   )rt   rv   rJ   rJ   rM   rw   æ  s    zFontRevisionStatement.buildrx   c             C   s   d  | j¡S )NzFontRevision {:.3f};)r”   rÛ   )rt   rz   rJ   rJ   rM   rh   é  s    zFontRevisionStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r)   Þ  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r0   z˜A ``GDEF`` table ``LigatureCaretByIndex`` statement. ``glyphs`` should be
    a `glyph-containing object`_, and ``carets`` should be a list of integers.Nc             C   s   t  | |¡ || | _| _d S )N)rA   ru   rˆ   Úcarets)rt   rˆ   rÜ   rs   rJ   rJ   rM   ru   ñ  s    z&LigatureCaretByIndexStatement.__init__c             C   s$   | j  ¡ }| | j|t| jƒ¡ dS )zBCalls the builder object's ``add_ligatureCaretByIndex_`` callback.N)rˆ   r…   Zadd_ligatureCaretByIndex_rs   ÚsetrÜ   )rt   rv   rˆ   rJ   rJ   rM   rw   õ  s    
z#LigatureCaretByIndexStatement.buildrx   c             C   s$   d  | j ¡ d dd„ | jD ƒ¡¡S )NzLigatureCaretByIndex {} {};rŒ   c             s   s   | ]}t |ƒV  qd S )N)rÇ   )rK   rÀ   rJ   rJ   rM   rN   ü  s    z6LigatureCaretByIndexStatement.asFea.<locals>.<genexpr>)r”   rˆ   rh   rO   rÜ   )rt   rz   rJ   rJ   rM   rh   ú  s    z#LigatureCaretByIndexStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r0   í  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r1   z–A ``GDEF`` table ``LigatureCaretByPos`` statement. ``glyphs`` should be
    a `glyph-containing object`_, and ``carets`` should be a list of integers.Nc             C   s   t  | |¡ || | _| _d S )N)rA   ru   rˆ   rÜ   )rt   rˆ   rÜ   rs   rJ   rJ   rM   ru     s    z$LigatureCaretByPosStatement.__init__c             C   s$   | j  ¡ }| | j|t| jƒ¡ dS )z@Calls the builder object's ``add_ligatureCaretByPos_`` callback.N)rˆ   r…   Zadd_ligatureCaretByPos_rs   rÝ   rÜ   )rt   rv   rˆ   rJ   rJ   rM   rw     s    
z!LigatureCaretByPosStatement.buildrx   c             C   s$   d  | j ¡ d dd„ | jD ƒ¡¡S )NzLigatureCaretByPos {} {};rŒ   c             s   s   | ]}t |ƒV  qd S )N)rÇ   )rK   rÀ   rJ   rJ   rM   rN     s    z4LigatureCaretByPosStatement.asFea.<locals>.<genexpr>)r”   rˆ   rh   rO   rÜ   )rt   rz   rJ   rJ   rM   rh     s    z!LigatureCaretByPosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r1      s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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             C   s4   t  | |¡ |||  | _| _| _|| | _| _d S )N)rA   ru   rº   rˆ   r»   r¼   Ú
forceChain)rt   rº   rˆ   r»   r¼   rÞ   rs   rJ   rJ   rM   ru     s    zLigatureSubstStatement.__init__c             C   sN   dd„ | j D ƒ}dd„ | jD ƒ}dd„ | jD ƒ}| | j|||| j| j¡ d S )Nc             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   #  s    z0LigatureSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   rr   rJ   rJ   rM   r¢   $  s    c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   %  s    )rº   rˆ   r»   Zadd_ligature_substrs   r¼   rÞ   )rt   rv   rº   rˆ   r»   rJ   rJ   rM   rw   "  s
    zLigatureSubstStatement.buildrx   c             C   sÆ   d}t | jƒst | jƒs| jrŠt | jƒrF|d dd„ | jD ƒ¡d 7 }|d dd„ | jD ƒ¡7 }t | jƒr¤|dd dd„ | jD ƒ¡ 7 }n|d dd„ | jD ƒ¡7 }|d7 }|t| jƒ7 }|d	7 }|S )
Nzsub rŒ   c             s   s   | ]}|  ¡ V  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   .  s    z/LigatureSubstStatement.asFea.<locals>.<genexpr>c             s   s   | ]}|  ¡ d  V  qdS )r¿   N)rh   )rK   rr   rJ   rJ   rM   rN   /  s    c             s   s   | ]}|  ¡ V  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   1  s    c             s   s   | ]}|  ¡ V  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   3  s    z by r°   )ro   rº   r»   rÞ   rO   rˆ   rh   r¼   )rt   rz   rž   rJ   rJ   rM   rh   *  s    

 zLigatureSubstStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r2     s   
c               @   s,   e Zd ZdZddd„Zdd„ Zdd	d
„ZdS )r3   zôA ``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             C   s"   t  | |¡ || _|| _|| _d S )N)rA   ru   r¬   ÚmarkAttachmentÚmarkFilteringSet)rt   r¬   rß   rà   rs   rJ   rJ   rM   ru   @  s    zLookupFlagStatement.__init__c             C   sH   d}| j dk	r| j  ¡ }d}| jdk	r0| j ¡ }| | j| j||¡ dS )z8Calls the builder object's ``set_lookup_flag`` callback.N)rß   r…   rà   Zset_lookup_flagrs   r¬   )rt   rv   Z
markAttachZ
markFilterrJ   rJ   rM   rw   H  s    



zLookupFlagStatement.buildrx   c             C   s¨   g }ddddg}d}x8t t|ƒƒD ](}| j|@ dkrB| || ¡ |d> }q"W | jd k	rn| d | j ¡ ¡¡ | jd k	rŽ| d | j ¡ ¡¡ |s˜d	g}d
 d |¡¡S )NZRightToLeftZIgnoreBaseGlyphsZIgnoreLigaturesZIgnoreMarksrj   r   zMarkAttachmentType {}zUseMarkFilteringSet {}Ú0zlookupflag {};rŒ   )	Úrangero   r¬   r   rß   r”   rh   rà   rO   )rt   rz   rž   ÚflagsrŠ   rÌ   rJ   rJ   rM   rh   R  s    

zLookupFlagStatement.asFea)r   NNN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r3   :  s   

c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r4   z…Represents a ``lookup ...;`` statement to include a lookup in a feature.

    The ``lookup`` should be a :class:`LookupBlock` object.Nc             C   s   t  | |¡ || | _| _d S )N)rA   ru   rs   rZ   )rt   rZ   rs   rJ   rJ   rM   ru   h  s    z!LookupReferenceStatement.__init__c             C   s   |  | jj¡ dS )z8Calls the builder object's ``add_lookup_call`` callback.N)Zadd_lookup_callrZ   rg   )rt   rv   rJ   rJ   rM   rw   l  s    zLookupReferenceStatement.buildrx   c             C   s   d  | jj¡S )Nz
lookup {};)r”   rZ   rg   )rt   rz   rJ   rJ   rM   rh   p  s    zLookupReferenceStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r4   c  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r5   z­A 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             C   s   t  | |¡ || | _| _d S )N)rA   ru   re   Úmarks)rt   re   rä   rs   rJ   rJ   rM   ru   y  s    zMarkBasePosStatement.__init__c             C   s   |  | j| j ¡ | j¡ dS )z:Calls the builder object's ``add_mark_base_pos`` callback.N)Zadd_mark_base_posrs   re   r…   rä   )rt   rv   rJ   rJ   rM   rw   }  s    zMarkBasePosStatement.buildrx   c             C   sR   d  | j ¡ ¡}x4| jD ]*\}}|d| t d  | ¡ |j¡ 7 }qW |d7 }|S )Nzpos base {}r¡   z{} mark @{}r°   )r”   re   rh   rä   r£   rg   )rt   rz   rž   ÚaÚmrJ   rJ   rM   rh     s
    &zMarkBasePosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r5   t  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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             C   s   t  | |¡ || | _| _d S )N)rA   ru   Ú	ligaturesrä   )rt   rç   rä   rs   rJ   rJ   rM   ru   ¤  s    zMarkLigPosStatement.__init__c             C   s   |  | j| j ¡ | j¡ dS )z9Calls the builder object's ``add_mark_lig_pos`` callback.N)Zadd_mark_lig_posrs   rç   r…   rä   )rt   rv   rJ   rJ   rM   rw   ¨  s    zMarkLigPosStatement.buildrx   c             C   s¶   d  | j ¡ ¡}g }xz| jD ]p}d}|d ks4t|ƒsJd| td  d }n8x6|D ].\}}|d| td  d  | ¡ |j¡ 7 }qPW | |¡ qW |d| t d  |¡7 }|d7 }|S )	Nzpos ligature {}rx   r¡   ri   z<anchor NULL>z{} mark @{}ZligComponentr°   )	r”   rç   rh   rä   ro   r£   rg   r   rO   )rt   rz   rž   ZligsÚlÚtemprå   ræ   rJ   rJ   rM   rh   ¬  s    (zMarkLigPosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r6   ‰  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r7   z°A 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             C   s   t  | |¡ || | _| _d S )N)rA   ru   Ú	baseMarksrä   )rt   rê   rä   rs   rJ   rJ   rM   ru   Æ  s    zMarkMarkPosStatement.__init__c             C   s   |  | j| j ¡ | j¡ dS )z:Calls the builder object's ``add_mark_mark_pos`` callback.N)Zadd_mark_mark_posrs   rê   r…   rä   )rt   rv   rJ   rJ   rM   rw   Ê  s    zMarkMarkPosStatement.buildrx   c             C   sR   d  | j ¡ ¡}x4| jD ]*\}}|d| t d  | ¡ |j¡ 7 }qW |d7 }|S )Nzpos mark {}r¡   z{} mark @{}r°   )r”   rê   rh   rä   r£   rg   )rt   rz   rž   rå   ræ   rJ   rJ   rM   rh   Î  s
    &zMarkMarkPosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r7   Á  s   
c               @   s,   e Zd ZdZddd„Zdd„ Zd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             C   s2   t  | |¡ |||  | _| _| _|| _|| _d S )N)rA   ru   rº   r‡   r»   r¼   rÞ   )rt   rº   r‡   r»   r¼   rÞ   rs   rJ   rJ   rM   ru   â  s    zMultipleSubstStatement.__init__c          	   C   s‚   dd„ | j D ƒ}dd„ | jD ƒ}| jsbt| jdƒrbxJ| j ¡ D ]}| | j|||| j| j¡ q>W n| | j|| j|| j| j¡ dS )z;Calls the builder object's ``add_multiple_subst`` callback.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   ì  s    z0MultipleSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   í  s    r…   N)	rº   r»   r¼   rl   r‡   r…   Zadd_multiple_substrs   rÞ   )rt   rv   rº   r»   r‡   rJ   rJ   rM   rw   ê  s$    zMultipleSubstStatement.buildrx   c             C   s¾   d}t | jƒst | jƒs| jrzt | jƒrB|d tt| jƒ¡d 7 }|t| jƒd 7 }t | jƒrˆ|dd tt| jƒ¡ 7 }n|t| jƒ7 }| jp”t	ƒ g}|d7 }|d tt|ƒ¡7 }|d7 }|S )Nzsub rŒ   r¿   z by r°   )
ro   rº   r»   rÞ   rO   r   rh   r‡   r¼   r„   )rt   rz   rž   r¼   rJ   rJ   rM   rh     s    

zMultipleSubstStatement.asFea)FN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r8   Ö  s   

c               @   s,   e Zd ZdZddd„Zdd„ Zd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             C   s2   t  | |¡ || _|| | _| _|| | _| _d S )N)rA   ru   Ú
enumeratedÚglyphs1Úvaluerecord1Úglyphs2Úvaluerecord2)rt   rì   rí   rî   rï   rë   rs   rJ   rJ   rM   ru     s    	zPairPosStatement.__init__c             C   sÌ   | j rf| j ¡ | j ¡ g}d}x2tj|Ž D ]$\}}d}| | j|| j|| j	¡ q*W |sbt
d| jƒ‚dS t| jtƒo|t| jtƒ}|r¤| | j| jj| j| jj| j	¡ n$| | 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``.
        FTz%Empty glyph class in positioning ruleN)rë   rì   r…   rî   Ú	itertoolsÚproductZadd_specific_pair_posrs   rí   rï   r   rm   r   r‡   Zadd_class_pair_pos)rt   rv   rr   Z	seen_pairZglyph1Zglyph2Zis_specificrJ   rJ   rM   rw   +  s4    	


zPairPosStatement.buildrx   c             C   sj   | j r
dnd}| jrB|d | j ¡ | j ¡ | j ¡ | j ¡ ¡7 }n$|d | j ¡ | j ¡ | j ¡ ¡7 }|S )Nzenum rx   zpos {} {} {} {};zpos {} {} {};)rë   rï   r”   rì   rh   rí   rî   )rt   rz   rž   rJ   rJ   rM   rh   V  s    zPairPosStatement.asFea)FN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r;     s
    
+c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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             C   s*   t  | |¡ || | _| _|| _|| _d S )N)rA   ru   Ú
old_prefixÚ
old_suffixrˆ   Úreplacements)rt   rò   ró   rˆ   rô   rs   rJ   rJ   rM   ru   o  s    z)ReverseChainSingleSubstStatement.__init__c          	   C   st   dd„ | j D ƒ}dd„ | jD ƒ}| jd  ¡ }| jd  ¡ }t|ƒdkrT|t|ƒ }| | j||tt	||ƒƒ¡ d S )Nc             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   v  s    z:ReverseChainSingleSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   w  s    r   rj   )
rò   ró   rˆ   r…   rô   ro   Zadd_reverse_chain_single_substrs   ÚdictÚzip)rt   rv   rº   r»   Ú	originalsÚreplacesrJ   rJ   rM   rw   u  s    z&ReverseChainSingleSubstStatement.buildrx   c             C   s¾   d}t | jƒst | jƒr„t | jƒr@|d dd„ | jD ƒ¡d 7 }|d dd„ | jD ƒ¡7 }t | jƒrš|dd dd„ | jD ƒ¡ 7 }n|d tt| jƒ¡7 }|d d dd„ | jD ƒ¡¡7 }|S )	Nzrsub rŒ   c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   „  s    z9ReverseChainSingleSubstStatement.asFea.<locals>.<genexpr>c             s   s   | ]}t |ƒd  V  qdS )r¿   N)rh   )rK   rr   rJ   rJ   rM   rN   …  s    c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   ‡  s    z by {};c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   Š  s    )	ro   rò   ró   rO   rˆ   r   rh   r”   rô   )rt   rz   rž   rJ   rJ   rM   rh   €  s    

  z&ReverseChainSingleSubstStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r<   f  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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             C   s0   t  | |¡ || | _| _|| _|| _|| _d S )N)rA   ru   rº   r»   rÞ   rˆ   rô   )rt   rˆ   Úreplacerº   r»   rÞ   rs   rJ   rJ   rM   ru   —  s
    zSingleSubstStatement.__init__c          	   C   sx   dd„ | j D ƒ}dd„ | jD ƒ}| jd  ¡ }| jd  ¡ }t|ƒdkrT|t|ƒ }| | j||tt	||ƒƒ| j
¡ dS )z9Calls the builder object's ``add_single_subst`` callback.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢      s    z.SingleSubstStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   ¡  s    r   rj   N)rº   r»   rˆ   r…   rô   ro   Zadd_single_substrs   r   rö   rÞ   )rt   rv   rº   r»   r÷   rø   rJ   rJ   rM   rw   ž  s    zSingleSubstStatement.buildrx   c             C   sÈ   d}t | jƒst | jƒs| jrŠt | jƒrF|d dd„ | jD ƒ¡d 7 }|d dd„ | jD ƒ¡7 }t | jƒr¤|dd dd„ | jD ƒ¡ 7 }n|d dd„ | jD ƒ¡7 }|d d d	d„ | jD ƒ¡¡7 }|S )
Nzsub rŒ   c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   ²  s    z-SingleSubstStatement.asFea.<locals>.<genexpr>c             s   s   | ]}t |ƒd  V  qdS )r¿   N)rh   )rK   rr   rJ   rJ   rM   rN   ³  s    c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   µ  s    c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   ·  s    z by {};c             s   s   | ]}t |ƒV  qd S )N)rh   )rK   rr   rJ   rJ   rM   rN   ¸  s    )ro   rº   r»   rÞ   rO   rˆ   r”   rô   )rt   rz   rž   rJ   rJ   rM   rh   ®  s    

  zSingleSubstStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r?   Ž  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r=   zA ``script`` statement.Nc             C   s   t  | |¡ || _d S )N)rA   ru   ra   )rt   ra   rs   rJ   rJ   rM   ru   ¿  s    zScriptStatement.__init__c             C   s   |  | j| j¡ dS )z,Calls the builder's ``set_script`` callback.N)Z
set_scriptrs   ra   )rt   rv   rJ   rJ   rM   rw   Ã  s    zScriptStatement.buildrx   c             C   s   d  | j ¡ ¡S )Nz
script {};)r”   ra   r­   )rt   rz   rJ   rJ   rM   rh   Ç  s    zScriptStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r=   ¼  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r>   zßA 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             C   s,   t  | |¡ |||  | _| _| _|| _d S )N)rA   ru   r^   rº   r»   rÞ   )rt   r^   rº   r»   rÞ   rs   rJ   rJ   rM   ru   Ò  s    zSinglePosStatement.__init__c             C   sJ   dd„ | j D ƒ}dd„ | jD ƒ}dd„ | jD ƒ}| | j|||| j¡ dS )z7Calls the builder object's ``add_single_pos`` callback.c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r½   rJ   rJ   rM   r¢   Ù  s    z,SinglePosStatement.build.<locals>.<listcomp>c             S   s   g | ]}|  ¡ ‘qS rJ   )r…   )rK   r    rJ   rJ   rM   r¢   Ú  s    c             S   s   g | ]\}}|  ¡ |f‘qS rJ   )r…   )rK   rr   r¬   rJ   rJ   rM   r¢   Û  s    N)rº   r»   r^   Zadd_single_posrs   rÞ   )rt   rv   rº   r»   r^   rJ   rJ   rM   rw   ×  s    zSinglePosStatement.buildrx   c             C   s¨   d}t | jƒst | jƒs| jr‚t | jƒrB|d tt| jƒ¡d 7 }|d dd„ | jD ƒ¡7 }t | jƒrœ|dd tt| jƒ¡ 7 }n|d dd„ | jD ƒ¡7 }|d7 }|S )Nzpos rŒ   c             S   s8   g | ]0}t |d  ƒd |d r.d|d   ¡  nd ‘qS )r   r¿   rj   rŒ   rx   )rh   )rK   rÀ   rJ   rJ   rM   r¢   å  s   z,SinglePosStatement.asFea.<locals>.<listcomp>c             S   s4   g | ],}t |d  ƒd |d r*|d   ¡ nd ‘qS )r   rŒ   rj   rx   )rh   )rK   rÀ   rJ   rJ   rM   r¢   í  s    r°   )ro   rº   r»   rÞ   rO   r   rh   r^   )rt   rz   rž   rJ   rJ   rM   rh   Þ  s    

zSinglePosStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r>   Ë  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )rE   zRepresents a subtable break.Nc             C   s   t  | |¡ d S )N)rA   ru   )rt   rs   rJ   rJ   rM   ru   ö  s    zSubtableStatement.__init__c             C   s   |  | j¡ dS )z<Calls the builder objects's ``add_subtable_break`` callback.N)Zadd_subtable_breakrs   )rt   rv   rJ   rJ   rM   rw   ù  s    zSubtableStatement.buildrx   c             C   s   dS )Nz	subtable;rJ   )rt   rz   rJ   rJ   rM   rh   ý  s    zSubtableStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   rE   ó  s   
c            
   @   sH   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ Zddd„Zdd„ Z	e	Z
dS )rG   zRepresents a value record.NFc             C   sN   t  | |
¡ || | _| _|| | _| _|| | _| _|| | _| _	|	| _
d S )N)r&   ru   Ú
xPlacementÚ
yPlacementÚxAdvanceÚyAdvanceÚ
xPlaDeviceÚ
yPlaDeviceÚ
xAdvDeviceÚ
yAdvDeviceÚvertical)rt   rú   rû   rü   rý   rþ   rÿ   r   r  r  rs   rJ   rJ   rM   ru     s    zValueRecord.__init__c             C   sH   | j |j koF| j|jkoF| j|jkoF| j|jkoF| j|jkoF| j|jkS )N)rú   rû   rü   rý   rþ   r   )rt   ÚotherrJ   rJ   rM   Ú__eq__  s    zValueRecord.__eq__c             C   s   |   |¡ S )N)r  )rt   r  rJ   rJ   rM   Ú__ne__"  s    zValueRecord.__ne__c             C   sP   t | jƒt | jƒA t | jƒA t | jƒA t | jƒA t | jƒA t | jƒA t | jƒA S )N)	Úhashrú   rû   rü   rý   rþ   rÿ   r   r  )rt   rJ   rJ   rM   Ú__hash__%  s    	zValueRecord.__hash__rx   c          
   C   sö   | sdS | j | j }}| j| j }}| j| j }}| j| j }}	| j}
|d kr~|d kr~|d krj|
rjt	|ƒS |d kr~|
s~t	|ƒS |p„d}|pŒd}|p”d}|pœd}|d krÎ|d krÎ|d krÎ|	d krÎd||||f S d||||t
|ƒt
|ƒt
|ƒt
|	ƒf S )Nz<NULL>r   z<%s %s %s %s>z<%s %s %s %s %s %s %s %s>)rú   rû   rü   rý   rþ   rÿ   r   r  r  rÇ   rQ   )rt   rz   rÀ   rÁ   rü   rý   rþ   rÿ   r   r  r  rJ   rJ   rM   rh   1  s<    zValueRecord.asFeac                s   t ‡ fdd„dD ƒƒS )Nc             3   s   | ]}t ˆ |ƒd k	V  qd S )N)Úgetattr)rK   Úv)rt   rJ   rM   rN   _  s   z'ValueRecord.__bool__.<locals>.<genexpr>)rú   rû   rü   rý   rþ   rÿ   r   r  )rÎ   )rt   rJ   )rt   rM   Ú__bool__]  s    
zValueRecord.__bool__)
NNNNNNNNFN)rx   )r|   r}   r~   r   ru   r  r  r  rh   r
  Ú__nonzero__rJ   rJ   rJ   rM   rG     s"            
	

,c               @   s$   e Zd ZdZddd„Zd	dd„ZdS )
rH   z+Represents a named value record definition.Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   rg   r¬   )rt   rg   r¬   rs   rJ   rJ   rM   ru   r  s    zValueRecordDefinition.__init__rx   c             C   s   d  | j ¡ | j¡S )NzvalueRecordDef {} {};)r”   r¬   rh   rg   )rt   rz   rJ   rJ   rM   rh   w  s    zValueRecordDefinition.asFea)N)rx   )r|   r}   r~   r   ru   rh   rJ   rJ   rJ   rM   rH   o  s   
c             C   sJ   | dkr|dkr|dkrdS | dkr8|dkr8|dkr8dS d  | ||¡S d S )Né   rj   i	  rx   r   Ú1z{} {} {})r”   )ÚpidZeidÚlidrJ   rJ   rM   Úsimplify_name_attributes{  s
    r  c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r9   z€Represents a name record. (`Section 9.e. <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.e>`_)Nc             C   s.   t  | |¡ || _|| _|| _|| _|| _d S )N)rA   ru   ÚnameIDÚ
platformIDÚ	platEncIDÚlangIDÚstring)rt   r  r  r  r  r  rs   rJ   rJ   rM   ru   ‡  s    zNameRecord.__init__c             C   s$   |  | j| j| j| j| j| j¡ dS )z8Calls the builder object's ``add_name_record`` callback.N)Zadd_name_recordrs   r  r  r  r  r  )rt   rv   rJ   rJ   rM   rw     s    zNameRecord.buildrx   c                s¶   dd„ ‰ t | j| j| jƒ}|d kr.td| jƒ‚t| j|d‰|dkrld ‡ ‡fdd„t	d	t
ˆƒd
ƒD ƒ¡}nd ‡ fdd„ˆD ƒ¡}t| j| j| jƒ}|dkr¦|d7 }d | j||¡S )Nc             S   s,   | dkr | dkr | dkr t | ƒS ||  S d S )Né    é~   )é"   é\   )Úchr)rÈ   Zescape_patternrJ   rJ   rM   Úescape›  s    z NameRecord.asFea.<locals>.escapezUnsupported encoding)ÚencodingÚ	utf_16_berx   c                s2   g | ]*}ˆ t ˆ| ƒd  t ˆ|d  ƒ dƒ‘qS )é   rj   z\%04x)r   )rK   rÌ   )r  r    rJ   rM   r¢   ©  s   z$NameRecord.asFea.<locals>.<listcomp>r   ri   c                s   g | ]}ˆ t |ƒd ƒ‘qS )z\%02x)r   )rK   Úb)r  rJ   rM   r¢   ®  s    rŒ   znameid {} {}"{}";)r   r  r  r  r   rs   r   r  rO   râ   ro   r  r”   r  )rt   rz   r  Zescaped_stringÚplatrJ   )r  r    rM   rh   š  s    zNameRecord.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r9   „  s   
c               @   s"   e Zd ZdZdd„ Zddd„ZdS )	r'   z4Represents a ``sizemenuname`` or ``name`` statement.c             C   s   t  | |¡ | | j¡ dS )z8Calls the builder object's ``add_featureName`` callback.N)r9   rw   Zadd_featureNamer  )rt   rv   rJ   rJ   rM   rw   ¸  s    zFeatureNameStatement.buildrx   c             C   sF   | j dkrd}nd}t| j| j| jƒ}|dkr6|d7 }d ||| j¡S )NÚsizeZsizemenunamerg   rx   rŒ   z
{} {}"{}";)r  r  r  r  r  r”   r  )rt   rz   rœ   r   rJ   rJ   rM   rh   ½  s    
zFeatureNameStatement.asFeaN)rx   )r|   r}   r~   r   rw   rh   rJ   rJ   rJ   rM   r'   µ  s   c               @   s   e Zd ZdZddd„ZdS )rD   z+Represents a STAT table ``name`` statement.rx   c             C   s0   t | j| j| jƒ}|dkr"|d7 }d || j¡S )Nrx   rŒ   zname {}"{}";)r  r  r  r  r”   r  )rt   rz   r   rJ   rJ   rM   rh   Ë  s    zSTATNameStatement.asFeaN)rx   )r|   r}   r~   r   rh   rJ   rJ   rJ   rM   rD   È  s   c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r@   zA ``parameters`` statement.Nc             C   s(   t  | |¡ || _|| _|| _|| _d S )N)rA   ru   Ú
DesignSizeÚSubfamilyIDÚ
RangeStartÚRangeEnd)rt   r"  r#  r$  r%  rs   rJ   rJ   rM   ru   Õ  s
    zSizeParameters.__init__c             C   s    |  | j| j| j| j| j¡ dS )z<Calls the builder object's ``set_size_parameters`` callback.N)Zset_size_parametersrs   r"  r#  r$  r%  )rt   rv   rJ   rJ   rM   rw   Ü  s    zSizeParameters.buildrx   c             C   sP   d  | j| j¡}| jdks$| jdkrH|d  t| jd ƒt| jd ƒ¡7 }|d S )Nzparameters {:.1f} {}r   z {} {}é
   r°   )r”   r"  r#  r$  r%  Úint)rt   rz   rž   rJ   rJ   rM   rh   æ  s    $zSizeParameters.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r@   Ò  s   

c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z;Represent a name statement inside a ``cvParameters`` block.Nc          	   C   s"   t j| ||||||d || _d S )N)rs   )r9   ru   r®   )rt   r  r  r  r  r  r®   rs   rJ   rJ   rM   ru   ð  s    z"CVParametersNameStatement.__init__c             C   sR   d}| j dkr$d |j | jd¡¡}| | j¡ | j| j | f| _t | |¡ dS )z9Calls the builder object's ``add_cv_parameter`` callback.rx   r¯   z_{}r   N)r®   r”   Zcv_num_named_params_Úgetr  Zadd_cv_parameterr9   rw   )rt   rv   ÚitemrJ   rJ   rM   rw   ø  s    
zCVParametersNameStatement.buildrx   c             C   s0   t | j| j| jƒ}|dkr"|d7 }d || j¡S )Nrx   rŒ   zname {}"{}";)r  r  r  r  r”   r  )rt   rz   r   rJ   rJ   rM   rh     s    zCVParametersNameStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r   í  s   
	c               @   s,   e Zd ZdZd
dd„Zdd„ Zd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             C   s   t  | |¡ || _|| _d S )N)rA   ru   Ú	characterrœ   )rt   r*  rœ   rs   rJ   rJ   rM   ru     s    zCharacterStatement.__init__c             C   s   |  | j| j¡ dS )z9Calls the builder object's ``add_cv_character`` callback.N)Zadd_cv_characterr*  rœ   )rt   rv   rJ   rJ   rM   rw     s    zCharacterStatement.buildrx   c             C   s   d  | j¡S )NzCharacter {:#x};)r”   r*  )rt   rz   rJ   rJ   rM   rh     s    zCharacterStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r!     s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r   z‡An axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList``
    pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair.Nc             C   s"   t  | |¡ || _|| _|| _d S )N)rA   ru   ÚbasesÚscriptsr  )rt   r+  r,  r  rs   rJ   rJ   rM   ru   !  s    zBaseAxis.__init__c             C   s   |  | j| j| j¡ dS )z6Calls the builder object's ``set_base_axis`` callback.N)Zset_base_axisr+  r,  r  )rt   rv   rJ   rJ   rM   rw   '  s    zBaseAxis.buildrx   c          	   C   s>   | j r
dnd}dd„ | jD ƒ}d |d | j¡||d |¡¡S )NZVertZHorizc             S   s2   g | ]*}d   |d |d d tt|d ƒ¡¡‘qS )z{} {} {}r   rj   rŒ   ri   )r”   rO   r   rÇ   )rK   rå   rJ   rJ   rM   r¢   .  s   z"BaseAxis.asFea.<locals>.<listcomp>z2{}Axis.BaseTagList {};
{}{}Axis.BaseScriptList {};rŒ   z, )r  r,  r”   rO   r+  )rt   rz   Ú	directionr,  rJ   rJ   rM   rh   +  s
    
zBaseAxis.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r     s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r:   zÔAn 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             C   s   t  | |¡ || _|| _d S )N)rA   ru   r«   r¬   )rt   r«   r¬   rs   rJ   rJ   rM   ru   ;  s    zOS2Field.__init__c             C   s   |  | j| j¡ dS )z6Calls the builder object's ``add_os2_field`` callback.N)Zadd_os2_fieldr«   r¬   )rt   rv   rJ   rJ   rM   rw   @  s    zOS2Field.buildrx   c                sŠ   dd„ ‰ d}d}t dd„ |D ƒƒ}| ‡ fdd„|D ƒ¡ dˆ g|d	< d
dd„ g|d< | j|kr†d || j d || j d | jƒ¡S dS )Nc             S   s   d  tt| ƒ¡S )NrŒ   )rO   r   rÇ   )rÀ   rJ   rJ   rM   Ú
intarr2strE  s    z"OS2Field.asFea.<locals>.intarr2str)ZFSTypeZTypoAscenderZTypoDescenderZTypoLineGapZ	winAscentZ
winDescentZXHeightZ	CapHeightZWeightClassZ
WidthClassZLowerOpSizeZUpperOpSize)ZUnicodeRangeZCodePageRangec             S   s   g | ]}|  ¡ |tgf‘qS rJ   )rp   rÇ   )rK   rÀ   rJ   rJ   rM   r¢   W  s    z"OS2Field.asFea.<locals>.<listcomp>c                s   g | ]}|  ¡ |ˆ gf‘qS rJ   )rp   )rK   rÀ   )r.  rJ   rM   r¢   X  s    ZPanoseZpanoseZVendorc             S   s
   d  | ¡S )Nz"{}")r”   )rÁ   rJ   rJ   rM   Ú<lambda>Z  ó    z OS2Field.asFea.<locals>.<lambda>Úvendorz{} {};r   rj   rx   )rõ   Úupdater«   r”   r¬   )rt   rz   ÚnumbersÚrangesÚkeywordsrJ   )r.  rM   rh   D  s    
"zOS2Field.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r:   6  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r*   zAn entry in the ``hhea`` table.Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   r«   r¬   )rt   r«   r¬   rs   rJ   rJ   rM   ru   e  s    zHheaField.__init__c             C   s   |  | j| j¡ dS )z7Calls the builder object's ``add_hhea_field`` callback.N)Zadd_hhea_fieldr«   r¬   )rt   rv   rJ   rJ   rM   rw   j  s    zHheaField.buildrx   c             C   s*   d}t dd„ |D ƒƒ}d || j | j¡S )N)ZCaretOffsetZAscenderZ	DescenderZLineGapc             S   s   g | ]}|  ¡ |f‘qS rJ   )rp   )rK   rÀ   rJ   rJ   rM   r¢   p  s    z#HheaField.asFea.<locals>.<listcomp>z{} {};)rõ   r”   r«   r¬   )rt   rz   Úfieldsr5  rJ   rJ   rM   rh   n  s    zHheaField.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r*   b  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )rI   zAn entry in the ``vhea`` table.Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   r«   r¬   )rt   r«   r¬   rs   rJ   rJ   rM   ru   w  s    zVheaField.__init__c             C   s   |  | j| j¡ dS )z7Calls the builder object's ``add_vhea_field`` callback.N)Zadd_vhea_fieldr«   r¬   )rt   rv   rJ   rJ   rM   rw   |  s    zVheaField.buildrx   c             C   s*   d}t dd„ |D ƒƒ}d || j | j¡S )N)ZVertTypoAscenderZVertTypoDescenderZVertTypoLineGapc             S   s   g | ]}|  ¡ |f‘qS rJ   )rp   )rK   rÀ   rJ   rJ   rM   r¢   ‚  s    z#VheaField.asFea.<locals>.<listcomp>z{} {};)rõ   r”   r«   r¬   )rt   rz   r6  r5  rJ   rJ   rM   rh   €  s    zVheaField.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   rI   t  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )rC   z²A 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             C   s(   t  | |¡ || _|| _|| _|| _d S )N)rA   ru   rœ   Ú	axisOrderÚnamesrs   )rt   rœ   r7  r8  rs   rJ   rJ   rM   ru     s
    z STATDesignAxisStatement.__init__c             C   s   |  | | j¡ d S )N)ZaddDesignAxisrs   )rt   rv   rJ   rJ   rM   rw   –  s    zSTATDesignAxisStatement.buildrx   c                sP   ˆ t 7 ‰ d| j› d| j› d}|dˆ   ‡ fdd„| jD ƒ¡d 7 }|d7 }|S )NzDesignAxis rŒ   z { 
r¡   c                s   g | ]}|j ˆ d ‘qS ))rz   )rh   )rK   r    )rz   rJ   rM   r¢   œ  s    z1STATDesignAxisStatement.asFea.<locals>.<listcomp>z};)r£   rœ   r7  rO   r8  )rt   rz   rž   rJ   )rz   rM   rh   ™  s
    &zSTATDesignAxisStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   rC   †  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r$   ziSTAT table ElidedFallbackName

    Args:
        names: a list of :class:`STATNameStatement` objects
    Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   r8  rs   )rt   r8  rs   rJ   rJ   rM   ru   ¨  s    zElidedFallbackName.__init__c             C   s   |  | j| j¡ d S )N)ÚsetElidedFallbackNamer8  rs   )rt   rv   rJ   rJ   rM   rw   ­  s    zElidedFallbackName.buildrx   c                s>   ˆ t 7 ‰ d}|dˆ   ‡ fdd„| jD ƒ¡d 7 }|d7 }|S )NzElidedFallbackName { 
r¡   c                s   g | ]}|j ˆ d ‘qS ))rz   )rh   )rK   r    )rz   rJ   rM   r¢   ³  s    z,ElidedFallbackName.asFea.<locals>.<listcomp>z};)r£   rO   r8  )rt   rz   rž   rJ   )rz   rM   rh   °  s
    &zElidedFallbackName.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r$   ¡  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r%   zpSTAT table ElidedFallbackNameID

    Args:
        value: an int pointing to an existing name table name ID
    Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   r¬   rs   )rt   r¬   rs   rJ   rJ   rM   ru   ¿  s    zElidedFallbackNameID.__init__c             C   s   |  | j| j¡ d S )N)r9  r¬   rs   )rt   rv   rJ   rJ   rM   rw   Ä  s    zElidedFallbackNameID.buildrx   c             C   s   d| j › dS )NzElidedFallbackNameID r°   )r¬   )rt   rz   rJ   rJ   rM   rh   Ç  s    zElidedFallbackNameID.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r%   ¸  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )rB   zÝA 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             C   s"   t  | |¡ || _|| _|| _d S )N)rA   ru   r8  Ú	locationsrã   )rt   r8  r:  rã   rs   rJ   rJ   rM   ru   Ô  s    zSTATAxisValueStatement.__init__c             C   s   |  | | j¡ d S )N)ZaddAxisValueRecordrs   )rt   rv   rJ   rJ   rM   rw   Ú  s    zSTATAxisValueStatement.buildrx   c       	      C   s¶   d}x| j D ]}|| ¡ 7 }qW x"| jD ]}|| ¡ 7 }|d7 }q(W | jrªddg}g }d}x8tt|ƒƒD ](}| j|@ dkrˆ| || ¡ |d> }qhW |dd |¡› d	7 }|d
7 }|S )NzAxisValue {
r¡   ZOlderSiblingFontAttributeZElidableAxisValueNamerj   r   zflag rŒ   z;
z};)r:  rh   r8  rã   râ   ro   r   rO   )	rt   rz   rž   rs   Z
nameRecordrã   ZflagStringsrŠ   rÌ   rJ   rJ   rM   rh   Ý  s"    zSTATAxisValueStatement.asFea)N)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   rB   Ë  s   
c               @   s$   e Zd ZdZddd„Zd	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             C   s   t  | |¡ || _|| _d S )N)rA   ru   rœ   Úvalues)rt   rœ   r;  rs   rJ   rJ   rM   ru   ü  s    z#AxisValueLocationStatement.__init__rx   c             C   s6   |d| j › d7 }|d dd„ | jD ƒ¡› d7 }|S )Nz	location rŒ   c             s   s   | ]}t |ƒV  qd S )N)rÇ   )rK   rÌ   rJ   rJ   rM   rN     s    z3AxisValueLocationStatement.asFea.<locals>.<genexpr>z;
)rœ   rO   r;  )rt   rž   rJ   rJ   rM   rh     s     z AxisValueLocationStatement.asFea)N)rx   )r|   r}   r~   r   ru   rh   rJ   rJ   rJ   rM   r   ó  s   
c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )r"   zÚ
    A variable layout conditionset

    Args:
        name (str): the name of this conditionset
        conditions (dict): a dictionary mapping axis tags to a
            tuple of (min,max) userspace coordinates.
    Nc             C   s   t  | |¡ || _|| _d S )N)rA   ru   rg   Ú
conditions)rt   rg   r<  rs   rJ   rJ   rM   ru     s    zConditionsetStatement.__init__c             C   s   |  | j| j¡ d S )N)Zadd_conditionsetrg   r<  )rt   rv   rJ   rJ   rM   rw     s    zConditionsetStatement.buildrx   c          	   C   sv   ||d| j › d d 7 }x<| j ¡ D ].\}\}}||t |› d|› d|› d 7 }q&W ||d d| j › d 7 }|S )Nzconditionset rŒ   z{
z;
Ú})rg   r<  r§   r£   )rt   rž   rz   rœ   ZminvalueZmaxvaluerJ   rJ   rM   rh     s
    &zConditionsetStatement.asFea)N)rx   rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r"     s   
c               @   s,   e Zd ZdZddd„Zdd„ Zdd	d
„ZdS )ÚVariationBlockzCA variation feature block, applicable in a given set of conditions.FNc             C   s&   t  | |¡ |||  | _| _| _d S )N)r   ru   rg   Úconditionsetr¤   )rt   rg   r?  r¤   rs   rJ   rJ   rM   ru   $  s    zVariationBlock.__init__c             C   s®   |  | j| j¡ | jdkr:| j|jkr:td| j› | jƒ‚|j}i |_t | |¡ xH|j 	¡ D ]:\}}|j
 |i ¡ | jg ¡}| |¡ ||kr^g ||< q^W ||_| ¡  dS )z‹Call the ``start_feature`` callback on the builder object, visit
        all the statements in this feature, and then call ``end_feature``.r†   z,variation block used undefined conditionset N)r¥   rs   rg   r?  Zconditionsets_r   r¦   r   rw   r§   Zfeature_variations_r¨   rŽ   r©   )rt   rv   rª   r«   r¬   r§   rJ   rJ   rM   rw   ,  s"    



zVariationBlock.buildrx   c             C   sb   |d| j  ¡   }|| jd 7 }| jr.|d7 }|d7 }|tj| |d7 }||d| j  ¡   7 }|S )Nzvariation %s rŒ   zuseExtension z{
)rz   z} %s;
)rg   r­   r?  r¤   r   rh   )rt   rz   rž   rJ   rJ   rM   rh   H  s    zVariationBlock.asFea)FN)rx   )r|   r}   r~   r   ru   rw   rh   rJ   rJ   rJ   rM   r>  !  s   
r>  )XZfontTools.feaLib.errorr   ZfontTools.feaLib.locationr   ZfontTools.misc.encodingToolsr   ZfontTools.misc.textToolsr   r   Úcollectionsr   rð   r£   Ú__all__rQ   rÝ   rq   rh   Ú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   r"   r>  rJ   rJ   rJ   rM   Ú<module>   sˆ  > -'%%::$$')8=S(.(n	1
,(