"Te^ddlmZddlmZddlmZddlmZddlm Z ddl m Z m Z m Z mZmZmZmZmZmZmZddlmZmZmZmZmZdd lmZmZdd lmZe r dd l m!Z!m"Z"m#Z#ed Z$Gd deZ%eee%ee%ee&e'ffee%e&e&ffZ(eGddeZ)GddZ*GddZ+e,dk(rddl-m!Z!ddl.m/Z/ddl0m1Z1dZ2e1jfdZ4e!Z e jkde jmde jmde jme/e2dd e jme jmd!e7e jqe4Z9e jme9e jme jmd"e jme4e jmd#y$y$)%)IntEnum) lru_cache) filterfalse) getLogger) attrgetter) TYPE_CHECKINGDictIterableList NamedTupleOptionalSequenceTupleTypeUnion)_is_single_cell_widthscached_cell_lencell_lenget_character_cell_size set_cell_size)Result rich_repr)Style)ConsoleConsoleOptions RenderResultrichcPeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZy) ControlTypezDNon-printable control codes which typically translate to ANSI codes.r N)__name__ __module__ __qualname____doc__BELLCARRIAGE_RETURNHOMECLEAR SHOW_CURSOR HIDE_CURSORENABLE_ALT_SCREENDISABLE_ALT_SCREEN CURSOR_UP CURSOR_DOWNCURSOR_FORWARDCURSOR_BACKWARDCURSOR_MOVE_TO_COLUMNCURSOR_MOVE_TO ERASE_IN_LINESET_WINDOW_TITLE./usr/lib/python3/dist-packages/rich/segment.pyr r #sYN DO D EKKIKNONMrEr cveZdZUdZeed<dZeeed<dZ ee e ed<e de fdZdefdZdefd Ze defd Zeed d dd e dedfdZd e dedfdZed/dZe d0deddeedeededfdZe d1deddededfdZededdeedfdZe d2dedde deedededeedf dZe d3dedde deedededf dZ ededde fdZ!edeeddee e ffd Z"e d4deedd!e d"ee deed#edeedf d$Z#e d1d%e$ddeedd!e d"e ded#edeedfd&Z%e d1d%e$ddeedd!e d"e ded#edeedfd'Z&e d1d%e$ddeedd!e d"e ded#edeedfd(Z'ededdedfd)Z(ededdedfd*Z)ededdedfd+Z*ededdedfd,Z+ededd-ee deedfd.Z,y)5SegmentaA piece of text with associated style. Segments are produced by the Console render process and are ultimately converted in to strings to be written to the terminal. Args: text (str): A piece of text. style (:class:`~rich.style.Style`, optional): An optional style to apply to the text. control (Tuple[ControlCode], optional): Optional sequence of control codes. Attributes: cell_length (int): The cell length of this Segment. textNstylecontrolreturnc,|\}}}|rdSt|S)zzThe number of terminal cells required to display self.text. Returns: int: A number of cells. r)r)selfrI_stylerKs rF cell_lengthzSegment.cell_lengthQs!!%fgq/$/rEc#K|j|j|j|jyy|j|jywN)rIrKrJrNs rF __rich_repr__zSegment.__rich_repr__[sHii << zz%jj &** ,, sAAc,t|jS)z#Check if the segment contains text.)boolrIrSs rF__bool__zSegment.__bool__dsDIIrEc|jduS)z,Check if the segment contains control codes.N)rKrSs rF is_controlzSegment.is_controlhs||4''rEi@segmentcut)rHrHc|\}}}t}|j}||k\r ||d||fSt}t||z t |dz z} |d| } t | } | |k(r|| ||||| d||fS| t |krm|| } | dz } | || z } |d| } | |k(r|| ||||| d||fS| |kDr#|| d| dz dz|||d|| dz||fS| t |krmt d)Nr zWill never reach here)rHrPrintlenrAssertionError) clsrZr[rIrJrK_SegmentrP cell_sizeposbeforecell_poschars rF _split_cellszSegment._split_cellsmsi 'eW)) + HR88 8+ 3$TQ78dsF# s?0cdUG4 CIo9D 1HC  $ 'H$3ZF3VUG4T#$Z8#~VIcAg.4eWES4:-ug>CIo 455rEc|\}}}t|r=|t|k\r|td||fSt|d|||t||d||fS|j||S)a0Split segment in to two segments at the specified column. If the cut point falls in the middle of a 2-cell wide character then it is replaced by two spaces, to preserve the display width of the parent segment. Returns: Tuple[Segment, Segment]: Two segments. r]N)rr`rHri)rNr[rIrJrKs rF split_cellszSegment.split_cellss{ $eW !$ 'c$iWR888Tc E73ST E73    s++rEc|dS)zMake a new line segment. rD)rbs rFlinez Segment.lines4yrEsegments post_stylec`|}|r|jfd|D}r fd|D}|S)aApply style(s) to an iterable of segments. Returns an iterable of segments where the style is replaced by ``style + segment.style + post_style``. Args: segments (Iterable[Segment]): Segments to process. style (Style, optional): Base style. Defaults to None. post_style (Style, optional): Style to apply on top of segment style. Defaults to None. Returns: Iterable[Segments]: A new iterable of segments (possibly the same iterable). c3NK|]\}}}||rdn||ywrRrD).0rIrOrKapplyrbs rF z&Segment.apply_style..s0)D&'D'$uV}gFs"%c3PK|]\}}}||rdn|r|zn|ywrRrD)rsrIrOrKrbrps rFruz&Segment.apply_style..sB *D&'#5;fz1 s#&)__add__)rbrorJrpresult_segmentsrts` ` @rF apply_stylezSegment.apply_stylesC&# MME-<O  .= OrErYcZ|rttd|Sttd|S)a2Filter segments by ``is_control`` attribute. Args: segments (Iterable[Segment]): An iterable of Segment instances. is_control (bool, optional): is_control flag to match in search. Returns: Iterable[Segment]: And iterable of Segment instances. rK)filterrr)rbrorYs rFfilter_controlzSegment.filter_controls+ *Y/: :z)4h? ?rEc#Kg}|j}|D]k}d|jvrS|jsG|\}}}|s&|jd\}} }|r||||| r|g}|j}|r=d||m|r|yyw)aSplit a sequence of segments in to a list of lines. Args: segments (Iterable[Segment]): Segments potentially containing line feeds. Yields: Iterable[List[Segment]]: Iterable of segment lists, one per line. rmN)appendrIrK partition) rbrornr~rZrIrJ__textnew_lines rF split_lineszSegment.split_liness! Gw||#GOO!(eQ,0NN4,@)E8Ts5%01" !!%w  J s6B .JsB''--Bsr^Nr)sumr~rPrKr) rbrnrrJr line_lengthrr~rZsegment_lengthrIrrs rFrzSegment.adjust_line_length7s&BTBB   3sf{.B'CU#K"LL&# 7"!6 !H__FK !(!4!4/&8GOO7O>1K-4*D-(v /CDD3t]34 AwHrEc8ttfd|DS)zGet the length of list of segments. Args: line (List[Segment]): A line encoded as a list of Segments (assumes no '\\n' characters), Returns: int: The length of the line. c3<K|]\}}}|r |ywrRrD)rsrIrJrK _cell_lens rFruz*Segment.get_line_length..osS';tUG79T?Ss  )rr)rbrnrs @rFget_line_lengthzSegment.get_line_lengthds StSSSrElinescf|j|rtfd|Dnd}|t|fS)zGet the shape (enclosing rectangle) of a list of lines. Args: lines (List[List[Segment]]): A list of lines (no '\\n' characters). Returns: Tuple[int, int]: Width and height in characters. c3.K|] }|ywrRrD)rsrnrs rFruz$Segment.get_shape..|s@$-@sr)rmaxr`)rbr max_widthrs @rF get_shapezSegment.get_shapeqs3--DIC@%@@q 3u:&&rEwidthheight new_linesc$|xs t|}|r|d|zdz|gn |d|z|g}|j}|d|} |D cgc] } || ||c} | ddt| |kr!| j|g|t| z z| Scc} w)aSet the shape of a list of lines (enclosing rectangle). Args: lines (List[List[Segment]]): A list of lines. width (int): Desired width. height (int, optional): Desired height or None for no change. style (Style, optional): Style of any padding added. new_lines (bool, optional): Padded lines should include " ". Defaults to False. Returns: List[List[Segment]]: New list of lines. r^rmN)rJ)r`rextend) rbrrrrJr_heightblankr shaped_linesrns rF set_shapezSegment.set_shapes*&CJ1:Sut#U + ,C%KQV@W?X !33Xg EJ =A tU% 8 Q | w &   7S5F+F G H  sB rbc|t|z }|s|ddS|d|}|r|d|zdz|n |d|z|}||gg|zz}|S)aAligns lines to top (adds extra lines to bottom as required). Args: lines (List[List[Segment]]): A list of lines. width (int): Desired width. height (int, optional): Desired height or None for no change. style (Style): Style of any padding added. new_lines (bool, optional): Padded lines should include " ". Defaults to False. Returns: List[List[Segment]]: New list of lines. Nr^rmr`rbrrrrJr extra_linesrs rF align_topzSegment.align_topsf*s5z) 8Ogv2;C%K$&.S5[RWAX% K// rEc|t|z }|s|ddS|d|}|r|d|zdz|n |d|z|}|gg|z|z}|S)aAligns render to bottom (adds extra lines above as required). Args: lines (List[List[Segment]]): A list of lines. width (int): Desired width. height (int, optional): Desired height or None for no change. style (Style): Style of any padding added. Defaults to None. new_lines (bool, optional): Padded lines should include " ". Defaults to False. Returns: List[List[Segment]]: New list of lines. Nr^rmrrs rF align_bottomzSegment.align_bottomsf*s5z) 8Ogv2;C%K$&.S5[RWAX K'%/ rEc|t|z }|s|ddS|d|}|r|d|zdz|n |d|z|}|dz}||z } |gg|z|z|gg| zz}|S)aAligns lines to middle (adds extra lines to above and below as required). Args: lines (List[List[Segment]]): A list of lines. width (int): Desired width. height (int, optional): Desired height or None for no change. style (Style): Style of any padding added. new_lines (bool, optional): Padded lines should include " ". Defaults to False. Returns: List[List[Segment]]: New list of lines. Nr^rmr!r) rbrrrrJrrr top_lines bottom_liness rF align_middlezSegment.align_middles*s5z) 8Ogv2;C%K$&.S5[RWAX1$ "Y.  I%-% L0HH rEc#&Kt|} t|}t}|D]X}|j|jk(r7|j s+||j |j z|j}S||}Z|y#t$rYywxYww)a)Simplify an iterable of segments by combining contiguous segments with the same style. Args: segments (Iterable[Segment]): An iterable of segments. Returns: Iterable[Segment]: A possibly smaller iterable of segments that will render the same way. N)iternext StopIterationrHrJrKrI)rbro iter_segments last_segmentrcrZs rFsimplifyzSegment.simplifysX   .L$ 'G!!W]]27??' %% 4l6H6H  #"&  '   s( B BA(B B B BBc#K|D]C}|js |j| |\}}}|||r|jdndEyw)zRemove all links from an iterable of styles. Args: segments (Iterable[Segment]): An iterable segments. Yields: Segment: Segments with link removed. N)rKrJ update_link)rbrorZrIrJ_controls rF strip_linkszSegment.strip_linkssV  LG'--"7 (/%eX$5 1 1$ 7dKK  LsA A c#:K|D]\}}}||d|yw)zRemove all styles from an iterable of segments. Args: segments (Iterable[Segment]): An iterable segments. Yields: Segment: Segments with styles replace with None NrD)rbrorIrOrKs rF strip_styleszSegment.strip_styles(s-&. + !D&'dD'* * +sc#Ki}|D]E\}}}|r1|j|}||j}|||<||||:||d|Gyw)zRemove all color from an iterable of segments. Args: segments (Iterable[Segment]): An iterable segments. Yields: Segment: Segments with colorless style. N)get without_color)rbrocacherIrJrKcolorless_styles rF remove_colorzSegment.remove_color5sl%'$, / D%"'))E"2"*&+&9&9O#2E%L$99$g.. /sAAcutsc#XKg}|j}t|} t|d}|dk(rgS|dk7rngd}|j}|j} t } |D]} | \} } }| s |r|n || | z}||kr || |}+||k(r9|| | ||}t|d}|dk(r |r | yi| j ||z \}} | \} } }||| ||}t|d}|dk(r |r | y| r| yw)zDivides an iterable of segments in to portions. Args: cuts (Iterable[int]): Cell positions where to divide. Yields: [Iterable[List[Segment]]]: An iterable of Segments in List. rN)r~rrrcopyrrk)rbrorsplit_segments add_segment iter_cutsr[resegments_clear segments_copyrrZrIrOrKend_posrfs rFdividezSegment.divideKsr+-$++ J y"%Cby axH '--&++ # # G$+ !D&'!(#cIdO.CS=(!Cc>('/)"$!Cy"-Cby)"//1'.&9&9#)&DOFG,3)D&'''/)"$C9b)"9%+o-C# JosA&D*)B4D* D*)rLrH)NNF)NTT)NT)NNF)-r0r1r2r3str__annotations__rJr rrKr ControlCodepropertyr_rPrrTrVrWrY classmethodrrrirkrnr ryr|r rrrrrrrrrrrrrrrrDrErFrHrH?s  I!E8E?!/3GXh{+ ,3 0S00v$(D((y#69#63#65AU;V#6#6J,s,u-A'B,,"&&* &9%&&UO & )  &&P?D@ *@8<@ ) @@$8I#68DO;T8 "&"& ,I9%,I,I ,I  ,I  ,I $y/ ",I,I\ "& *9o** *  * i **X T4 ? Ts T T 'd4 ?3 'c3h ' ' !%!% !DO$!! !  !  ! d9o !!F  )_DO$      d9o 8  )_DO$      d9o 8  )_DO$      d9o < 38K4L8I#6L8I;NLL  +HY$7 +HY><<>D==    }} $ $sA A A ArrrrrrLr) r0r1r2r3r rHrVrrrDrErFrrsD#'!2#t#PT# %  %+; %  %rErcBeZdZddeeededdfdZ ddZy) SegmentLinesrrrLNc2t||_||_y)a=A simple renderable containing a number of lines of segments. May be used as an intermediate in rendering process. Args: lines (Iterable[List[Segment]]): Lists of segments forming lines. new_lines (bool, optional): Insert new lines after each line. Defaults to False. N)rrr)rNrrs rFrzSegmentLines.__init__s%[ "rEc#K|jr4tj}|jD]}|Ed{|y|jD] }|Ed{y7'7 wrR)rrHrnr)rNrrrrns rFrzSegmentLines.__rich_console__s` >>||~H        s!5A#AA#A!A#!A#rr) r0r1r2r r rHrVrrrDrErFrrsC #htG}5 #$ #SW #     +;    rEr__main__)r)Syntax)Textzfrom rich.console import Console console = Console() text = Text.from_markup("Hello, [bold magenta]World[/]!") console.print(text)zHello, [bold magenta]World[/]!z rich.Segmentz]A Segment is the last step in the Rich render process before generating text with ANSI codes.z Consider the following code: pythonT) line_numberszRWhen you call [b]print()[/b], Rich [i]renders[/i] the object in to the following: zAThe Segments are then processed to produce the following output: zS You will only need to know this if you are implementing your own Rich renderables.N):enumr functoolsr itertoolsrloggingroperatorrtypingrr r r r r rrrrcellsrrrrrreprrrrJrrrrrlogr r_rrrHrrr0 rich.console rich.syntaxr rich.textrcode from_markuprIruleprintrrender fragmentsrDrErFrs!   $>>'* + +uS#X &' +sC  "  N jN  N b%%2  2 z$" D 4  < =DiG LL  MMg MM45 MM&xd;< MMO MM]W^^D)*I MM) MMO MMVW MM$ MM^;rE