o
    Ph$F                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ dZ	G dd de
ZG d	d
 d
ejZejj e_ G dd deZdd Zdd ZdS )z&Module providing 'sequence awareness'.    N)wcwidth)TextType)CAPABILITIES_CAUSE_MOVEMENT)SequenceSequenceTextWrapper
iter_parsemeasure_lengthc                   @   s`   e Zd ZdZdd Zdd Zedd Zedd	 Zed
d Z	dd Z
e			dddZdS )Termcapz7Terminal capability of given variable name and pattern.c                 C   s   || _ || _|| _d| _dS )z
        Class initializer.

        :arg str name: name describing capability.
        :arg str pattern: regular expression string.
        :arg str attribute: :class:`~.Terminal` attribute used to build
            this terminal capability.
        N)namepattern	attribute_re_compiled)selfr
   r   r    r   L/var/www/html/env_mimamsha/lib/python3.10/site-packages/blessed/sequences.py__init__   s   	
zTermcap.__init__c                 C      dj | dS )Nz&<Termcap {self.name}:{self.pattern!r}>r   formatr   r   r   r   __repr__%   s   zTermcap.__repr__c                 C   r   )z;Regular expression pattern for capability with named group.z(?P<{self.name}>{self.pattern})r   r   r   r   r   r   named_pattern)   s   zTermcap.named_patternc                 C   s   | j du rt| j| _ | j S )z3Compiled regular expression pattern for capability.N)r   recompiler   r   r   r   r   re_compiled/   s   
zTermcap.re_compiledc                 C   s
   | j tv S )z*Whether capability causes cursor movement.)r
   r   r   r   r   r   	will_move6   s   
zTermcap.will_movec                 C   s`   dddddd | j}|dur|S ddd | j}|dur.t| j|d}|| S dS )a4  
        Horizontal carriage adjusted by capability, may be negative.

        :rtype: int
        :arg str text: for capabilities *parm_left_cursor*, *parm_right_cursor*, provide the
            matching sequence text, its interpreted distance is returned.
        :returns: 0 except for matching '
              )cursor_left	backspacecursor_righttab	ascii_tabN)parm_left_cursorparm_right_cursorr   )getr
   intr   matchgroup)r   textvalueunitr   r   r   horizontal_distance;   s&   
zTermcap.horizontal_distancer   c   Fc	                    s   d |rd |r
d |du rdn|}|dkr| |t ||S t ||f|  }	|sMt|d |d D ]}
t|
|	v rL|	t|
 }| |||  S q4|r[t d fd	d
|	}nt d fdd
|	}| |||S )ak  
        Class factory builder for given capability definition.

        :arg str name: Variable name given for this pattern.
        :arg str capability: A unicode string representing a terminal
            capability to build for. When ``nparams`` is non-zero, it
            must be a callable unicode string (such as the result from
            ``getattr(term, 'bold')``.
        :arg str attribute: The terminfo(5) capability name by which this
            pattern is known.
        :arg int nparams: number of positional arguments for callable.
        :arg int numeric: Value to substitute into capability to when generating pattern
        :arg bool match_grouped: If the numeric pattern should be
            grouped, ``(\d+)`` when ``True``, ``\d+`` default.
        :arg bool match_any: When keyword argument ``nparams`` is given,
            *any* numeric found in output is suitable for building as
            pattern ``(\d+)``.  Otherwise, only the first matching value of
            range *(numeric - 1)* through *(numeric + 1)* will be replaced by
            pattern ``(\d+)`` in builder.
        :arg bool match_optional: When ``True``, building of numeric patterns
            containing ``(\d+)`` will be built as optional, ``(\d+)?``.
        :rtype: blessed.sequences.Termcap
        :returns: Terminal capability instance for given capability definition
        z\d+z(\d+)z(\d+)?Nr.   r   r      c                        S Nr   x_numeric_regexr   r   <lambda>       zTermcap.build.<locals>.<lambda>c                    r0   r1   r   r2   r4   r   r   r6      r7   )r   escaperangestrreplacesub)clsr
   
capabilityr   nparamsnumericmatch_grouped	match_anymatch_optional_outpnumr   r   r4   r   buildY   s&   zTermcap.buildN)r   r.   FFF)__name__
__module____qualname____doc__r   r   propertyr   r   r   r-   classmethodrF   r   r   r   r   r	      s     


r	   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   zDocstring overridden.c                 K   s    || _ tjj| |fi | dS )ze
        Class initializer.

        This class supports the :meth:`~.Terminal.wrap` method.
        N)termtextwrapTextWrapperr   )r   widthrM   kwargsr   r   r   r      s   zSequenceTextWrapper.__init__c           
      C   s:  g }| j dkst| j tstd| j t| j | j}t| d p$| j}|	  |rg }d}|r4| j
n| j}| j t| }|rPt|d | dkrP|rP|d= |r{t|d | }	||	 |krn|	|krm| |||| n||  ||	7 }|sR|r|rt|d | dkr|d= |r||d|  |s+|S )a4  
        Sequence-aware variant of :meth:`textwrap.TextWrapper._wrap_chunks`.

        :raises ValueError: ``self.width`` is not a positive integer
        :rtype: list
        :returns: text chunks adjusted for width

        This simply ensures that word boundaries are not broken mid-sequence, as standard python
        textwrap would incorrectly determine the length of a string containing sequences, and may
        also break consider sequences part of a "word" that may be broken by hyphen (``-``), where
        this implementation corrects both.
        r   z0invalid width {0!r}({1!r}) (must be integer > 0)drop_whitespacer    )rP   
isinstancer'   
ValueErrorr   typerM   hasattrrR   reversesubsequent_indentinitial_indentlenr   striplength_handle_long_wordappendpopjoin)
r   chunkslinesrM   rR   cur_linecur_lenindentrP   	chunk_lenr   r   r   _wrap_chunks   sJ   z SequenceTextWrapper._wrap_chunksc                 C   s   |dk rdn|| }| j r_| j}|d }d }}	t||D ].\}
}|	t|
7 }	t|d|	 | }||krI|dkrG|dkrG|	dkrG|dkrGn n|	}q||d|  ||d |d< dS |sj||  dS dS )a  
        Sequence-aware :meth:`textwrap.TextWrapper._handle_long_word`.

        This method ensures that word boundaries are not broken mid-sequence, as
        standard python textwrap would incorrectly determine the length of a
        string containing sequences and wide characters it would also break
        these "words" that would be broken by hyphen (``-``), this
        implementation corrects both.

        This is done by mutating the passed arguments, removing items from
        'reversed_chunks' and appending them to 'cur_line'.

        However, some characters (east-asian, emoji, etc.) cannot be split any
        less than 2 cells, so in the case of a width of 1, we have no choice
        but to allow those characters to flow outside of the given cell.
        r   r   r   Nr/   )break_long_wordsrM   r   r[   r   r]   r_   r`   )r   reversed_chunksrd   re   rP   
space_leftrM   chunkidxnxtr*   _
seq_lengthr   r   r   r^      s$    z%SequenceTextWrapper._handle_long_wordN)rG   rH   rI   rJ   r   rh   r^   r   r   r   r   r      s
    	.r   c                   @   sv   e Zd ZdZdd ZdddZdddZdd	d
Zdd Zdd Z	dddZ
dddZdddZdd ZdddZdS )r   a  
    A "sequence-aware" version of the base :class:`str` class.

    This unicode-derived class understands the effect of escape sequences
    of printable length, allowing a properly implemented :meth:`rjust`,
    :meth:`ljust`, :meth:`center`, and :meth:`length`.
    c                 C   s   t | |}||_|S )z
        Class constructor.

        :arg str sequence_text: A string that may contain sequences.
        :arg blessed.Terminal term: :class:`~.Terminal` instance.
        )r   __new___term)r=   sequence_textrM   newr   r   r   rq     s   zSequence.__new__ c                 C   s<   |t tdt| |   tt|  }d| |fS )aq  
        Return string containing sequences, left-adjusted.

        :arg int width: Total width given to left-adjust ``text``.  If
            unspecified, the width of the attached terminal is used (default).
        :arg str fillchar: String for padding right-of ``text``.
        :returns: String of ``text``, left-aligned by ``width``.
        :rtype: str
                rS   r'   maxfloat	__index__r]   r[   ra   )r   rP   fillchar	rightsider   r   r   ljust     
$zSequence.ljustc                 C   s<   |t tdt| |   tt|  }d|| fS )as  
        Return string containing sequences, right-adjusted.

        :arg int width: Total width given to right-adjust ``text``.  If
            unspecified, the width of the attached terminal is used (default).
        :arg str fillchar: String for padding left-of ``text``.
        :returns: String of ``text``, right-aligned by ``width``.
        :rtype: str
        rv   rS   rw   )r   rP   r{   leftsider   r   r   rjust&  r~   zSequence.rjustc                 C   sv   t dt| |   d }|tt dt|tt|  }|tt dt|tt|  }d	|| |fS )al  
        Return string containing sequences, centered.

        :arg int width: Total width given to center ``text``.  If
            unspecified, the width of the attached terminal is used (default).
        :arg str fillchar: String for padding left and right-of ``text``.
        :returns: String of ``text``, centered by ``width``.
        :rtype: str
        rv   r/   rS   )
rx   ry   rz   r]   r'   mathfloorr[   ceilra   )r   rP   r{   splitr   r|   r   r   r   center4  s   
zSequence.centerc                 C   sp   d}d}|  }t| j|  }|D ]\}}|s'|tt|d7 }||kr' n||7 }q|ddd |D  S )a  
        Truncate a string in a sequence-aware manner.

        Any printable characters beyond ``width`` are removed, while all
        sequences remain in place. Horizontal Sequences are first expanded
        by :meth:`padd`.

        :arg int width: The printable width to truncate the string to.
        :rtype: str
        :returns: String truncated to at most ``width`` printable characters.
        rS   r   c                 s   s    | ]	\}}|r|V  qd S r1   r   ).0r*   capr   r   r   	<genexpr>`  s    z$Sequence.truncate.<locals>.<genexpr>)rz   r   rr   paddrx   r   ra   )r   rP   outputcurrent_widthtarget_width
parsed_seqr*   r   r   r   r   truncateE  s   
zSequence.truncatec                 C   s   t dd | jddD S )u  
        Return the printable length of string containing sequences.

        Strings containing ``term.left`` or ``\b`` will cause "overstrike",
        but a length less than 0 is not ever returned. So ``_\b+`` is a
        length of 1 (displays as ``+``), but ``\b`` alone is simply a
        length of 0.

        Some characters may consume more than one cell, mainly those CJK
        Unified Ideographs (Chinese, Japanese, Korean) defined by Unicode
        as half or full-width characters.

        For example:

            >>> from blessed import Terminal
            >>> from blessed.sequences import Sequence
            >>> term = Terminal()
            >>> msg = term.clear + term.red(u'コンニチハ')
            >>> Sequence(msg, term).length()
            10

        .. note:: Although accounted for, strings containing sequences such
            as ``term.clear`` will not give accurate returns, it is not
            considered lengthy (a length of 0).
        c                 s   s    | ]
}t t|d V  qdS )r   N)rx   r   )r   w_charr   r   r   r   }  s    z"Sequence.length.<locals>.<genexpr>Tr\   )sumr   r   r   r   r   r]   b  s   zSequence.lengthNc                 C      |   |S )a	  
        Return string of sequences, leading and trailing whitespace removed.

        :arg str chars: Remove characters in chars instead of whitespace.
        :rtype: str
        :returns: string of sequences with leading and trailing whitespace removed.
        )
strip_seqsr\   r   charsr   r   r   r\        zSequence.stripc                 C   r   )z
        Return string of all sequences and leading whitespace removed.

        :arg str chars: Remove characters in chars instead of whitespace.
        :rtype: str
        :returns: string of sequences with leading removed.
        )r   lstripr   r   r   r   r     r   zSequence.lstripc                 C   r   )z
        Return string of all sequences and trailing whitespace removed.

        :arg str chars: Remove characters in chars instead of whitespace.
        :rtype: str
        :returns: string of sequences with trailing removed.
        )r   rstripr   r   r   r   r     r   zSequence.rstripc                 C   s   | j ddS )z
        Return ``text`` stripped of only its terminal sequences.

        :rtype: str
        :returns: Text with terminal sequences removed
        Tr   )r   r   r   r   r   r     s   zSequence.strip_seqsFc                 C   sn   d}t | j| D ],\}}|s||7 }q||}|dkr#|d| 7 }q|dk r.|d| }q|s4||7 }q|S )z
        Return non-destructive horizontal movement as destructive spacing.

        :arg bool strip: Strip terminal sequences
        :rtype: str
        :returns: Text adjusted for horizontal movement
        rS   r   ru   N)r   rr   r-   )r   r\   outpr*   r   r+   r   r   r   r     s   
zSequence.padd)ru   r1   )F)rG   rH   rI   rJ   rq   r}   r   r   r   r]   r\   r   r   r   r   r   r   r   r   r     s    








	r   c                 c   sL    | j |D ]}|j}||}|dkr|dfV  q|| j| fV  qdS )z
    Generator yields (text, capability) for characters of ``text``.

    value for ``capability`` may be ``None``, where ``text`` is
    :class:`str` of length 1.  Otherwise, ``text`` is a full
    matching sequence of given capability.
    MISMATCHN)_caps_compiled_anyfinditer	lastgroupr)   caps)rM   r*   r(   r
   r+   r   r   r   r     s   
r   c                 C   s<   zt t|| \} }|rt| W S W dS  ty   Y dS w )zk
    .. deprecated:: 1.12.0.

    :rtype: int
    :returns: Length of the first sequence in the string
    r   )nextr   r[   StopIteration)r*   rM   r>   r   r   r   r     s   
r   )rJ   r   r   rN   r   blessed._compatr   blessed._capabilitiesr   __all__objectr	   rO   r   r   r   r   r   r   r   r   <module>   s   {
q <