
    LT                         S r SSKJr  SSKJr  SSKJr  SSKrSSKJr  SSKJ	r	  SSK
Jr   " S	 S
\	R                  5      rg)a{  Cloud SDK markdown document token renderer.

This is different from the other renderers:

(1) The output is a list of (token, text) tuples returned by
    TokenRenderer.Finish().
(2) A token is an empty object that conveys font style and embellishment by
    convention using the token name. Callers set up a style sheet indexed by
    tokens to control how the embellishments are rendered, e.g. color.
(3) The rendering is constrained by width and height.

Tokens generated by this module:

  Token.Markdown.Bold: bold text
  Token.Markdown.BoldItalic: bold+italic text
  Token.Markdown.Code: code text for command line examples
  Token.Markdown.Definition: definition list item (flag or subcommand or choice)
  Token.Markdown.Italic: italic text
  Token.Markdown.Normal: normal text
  Token.Markdown.Section: section header
  Token.Markdown.Truncated: the last token => indicates truncation
  Token.Markdown.Value: definition list item value (flag value)

The Token objects self-define on first usage. Don't champion this pattern in the
Cloud SDK.

Usage:

  from six.moves import StringIO

  from googlecloudsdk.core.document_renderers import token_renderer
  from googlecloudsdk.core.document_renderers import render_document

  markdown = <markdown document string>
  tokens = render_document.MarkdownRenderer(
      token_renderer.TokenRenderer(width=W, height=H),
      StringIO(markdown)).Run()
    )absolute_import)division)unicode_literalsN)console_attr)renderer)Tokenc                     ^  \ rS rSrSrSr\R                  R                  \R                  R                  \R                  R                  \R                  R                  \R                  R                  S.rSrSrSrSr " S	 S
\5      rS"U 4S jjrS rS#S jrS rS#S jrS rS rS rS$S jrS rS rS rS#S jr S r!S r"S%S jr#S r$S r%S&S jr&S r'S'S jr(S(S  jr)S!r*U =r+$ ))TokenRendererB   a6  Renders markdown to a list of lines where each line is a list of Tokens.

Attributes:
  _attr: console_attr.ConsoleAttr object.
  _bullet: List of bullet characters indexed by list level modulo #bullets.
  _compact: Compact representation if True. Saves rendering real estate.
  _csi: The control sequence indicator character. Token does not have control
    sequences. This renderer uses them internally to manage font styles and
    attributes (bold, code, italic).
  _current_token_type: current default Token.Markdown.* type
  _fill: The number of characters in the current output line.
  _height: The height of the output window, 0 to disable height checks.
  _ignore_paragraph: Ignore paragraph markdown until the next non-space
    _AddToken.
  _ignore_width: True if the next output word should ignore _width.
  _indent: List of left indentations in characters indexed by _level.
  _level: The section or list level counting from 0.
  _tokens: The list of output tokens
  _truncated: The number of output lines exceeded the output height.
  _rows: current rows in table
 )BCINZ      r      c                   "    \ rS rSrSrSS jrSrg)TokenRenderer.Indenti   zSecond line indent stack.c                 b    U(       a  SO[         R                  U l        U R                  U l        g )Nr   )r
   INDENTindentsecond_line_indent)selfcompacts     <lib/googlecloudsdk/core/document_renderers/token_renderer.py__init__TokenRenderer.Indent.__init__l   s     Am&:&:dk $d    r   r   N)T)__name__
__module____qualname____firstlineno____doc__r   __static_attributes__ r!   r   Indentr   i   s
    #,r!   r*   c                   > [         [        U ]
  " S0 UD6  [        R                  " US9U l        U R                  U l        U R                  U R
                  l        U R
                  R                  5       U l	        X0l
        SU l        [        R                  R                  U l        Xl        SU l        SU l        U R'                  U5      /U l        SU l        / U l        / U l        SU l        / U l        g )N)encodingr   Fr)   )superr
   r   r   GetConsoleAttr_attrCSI_csi
GetBullets_bullet_compact_fillr   MarkdownNormal_current_token_type_height_ignore_paragraph_ignore_widthr*   _indent_level_lines_tokens
_truncated_rows)r   heightr,   r   kwargs	__class__s        r   r   TokenRenderer.__init__p   s    	-'1&1,,h?DJDIiiDJJO::((*DLMDJ$~~44DL"DDKK()DLDKDKDLDODJr!   c                 Z   SU l         Sn[        U5      n[        R                  R                  U4nU(       a  U(       a  Uu  pgXG:X  a  OUS-   U::  a:  SU R                  U5      SXt-
  S-
   -   nUR                  U R                  U45        O/ nU R                  nU Hx  n	XR                     nU R                  R                  U5      n
Xz-  nXt::  a2  XG-
  nU(       a  USU*  nUR                  XR                     U45          OUR                  U	5        Mz     UnUR                  U5        U$ )a;  Injects a truncation indicator token and rejects subsequent tokens.

Args:
  tokens: The last line of tokens at the output height. The part of the line
    within the output width will be visible, modulo the trailing truncation
    marker token added here.
  overflow: If not None then this is a (word, available) tuple from Fill()
    where word caused the line width overflow and available is the number of
    characters available in the current line before ' '+word would be
    appended.

Returns:
  A possibly altered list of tokens that form the last output line.
Tz...r    N)r@   lenr   r6   	Truncated	_UnFormatappendr8   _widthTOKEN_TEXT_INDEXr/   DisplayWidthTOKEN_TYPE_INDEX)r   tokensoverflowmarker_stringmarker_widthmarker_tokenword	availabletruncated_tokenstokenwidthtrims               r   	_TruncateTokenRenderer._Truncate   s2    DOM}%LNN,,m<L( od		"1*T^^D)*HI,Dq,HIIt//67 KK	E,,-$**))$/%

)&+D&D5\d##U+@+@%A4$HI

!
!%
(  "
MM,Mr!   c                    U R                   n/ U l         U R                  (       d  U(       d  U R                  (       a  gU R                  (       a  U R                  S   (       a  U R                  S   S   U R                     R                  5       (       ag  U R                  S   SS U R                  S'   U R                  S   (       a4  U R                  S   S   U R                     R                  5       (       a  Mg  U R                  (       aI  [        U R                  5      [        [        U5      5      -   U R                  :  a  U R                  X!5      nU R                  R                  U5        g)a!  Adds the current token list to the line list.

Args:
  overflow: If not None then this is a (word, available) tuple from Fill()
    where word caused the line width overflow and available is the number of
    characters available in the current line before ' '+word would be
    appended.
N)r?   r@   r4   r>   rM   isspacer9   rH   intboolr[   rK   )r   rQ   rP   s      r   _NewLineTokenRenderer._NewLine   s     \\FDLf{{ ++b/kk"ob!$"7"78@@BB++b/#2.B ++b/kk"ob!$"7"78@@BB ||T[[)CV,==$,,N~~f/fKKvr!   c                    U(       d  gU R                   (       a   U R                   S   U R                     U:w  a  U R                   R                  X!45        gU R                   S   U R                     [        R                  R
                  :X  a  U R                   S   U R                     n[        R                  " SU5      R                  S5      n[        R                  " SU5      R                  S5      nXE:X  a  X!4U R                   S'   gU R                  5         U R                   R                  X!45        gUU R                   S   U R                     U-   4U R                   S'   g)zFMerges text if the previous token_type matches or appends a new token.Nr^   z( *)r   )r?   rO   rK   r   r6   SectionrM   rematchgrouprb   )r   text
token_typeprv_text
prv_indent
new_indents         r   _MergeOrAddTokenTokenRenderer._MergeOrAddToken   s   LL<<D112j@
ll:,-	b	$//	0ENN4J4J	Jb!$"7"78h88FH-33A6j88FD)//2j		!&-R 	Z./ 
,,r
400
1D
8dll2r!   c                    U(       a  UR                  5       (       d  SU l        U(       d  U R                  nU R                  U;  a  U R	                  X5        gSn UR                  U R                  U5      nUS:  a  U R	                  XS U5        gU R	                  XU U5        U R                  XS-         nX l        US-   nMl  )z7Appends a (token_type, text) tuple to the current line.Fr   Nr   r   )r_   r:   r8   r1   rn   findEMBELLISHMENTS)r   ri   rj   ijs        r   	_AddTokenTokenRenderer._AddToken   s    DLLNN$d++jyy
D-
aIIdii#q5


R*
5
dQi4((!e5
#- E r!   c                 ,   U R                   U;  a  U$ / nSnU[        U5      :  a_  UR                  U R                   U5      nUS:  a  UR                  XS 5        O)UR                  XU 5        US-   nU[        U5      :  a  M_  SR	                  U5      $ )z1Returns text with all inline formatting stripped.r   Nr    )r1   rH   rq   rK   join)r   ri   strippedrs   rt   s        r   rJ   TokenRenderer._UnFormat   s    yykH	A
c$i-
))DIIq
!a	
QR!oodQi 
a%a c$i- 778r!   c                    U R                  U5      nUR                  SS5      nU R                  US   [        R                  R
                  5        [        U5      S:  aW  U R                  S[        R                  R                  5        U R                  US   [        R                  R                  5        U R                  5         g)z>Appends a definition list definition item to the current line.=r   r   N)
rJ   splitru   r   r6   
DefinitionrH   r7   Valuerb   )r   ri   partss      r   _AddDefinitionTokenRenderer._AddDefinition  s    >>$DJJsAENN58U^^667
5zA~
nnS%..//0
nnU1Xu~~334MMOr!   c                     SU l         U R                  (       a(  U R                  5         U R                  5         SU l        gg)z/Flushes the current collection of Fill() lines.Fr   N)r;   r5   rb   Contentr   s    r   _FlushTokenRenderer._Flush  s/    Dzz
mmo
llndj r!   c                    U R                   U:  Ga  U R                   U:  Ga  U R                   nU =R                   S-  sl         U R                   [        U R                  5      :  a)  U R                  R                  U R	                  5       5        U R                  U   R
                  U-   U R                  U R                      l        U R                   S:  a`  U R                  U   R                  U R                  U   R
                  :X  a,  U R                  U R                      =R
                  S-  sl        U R                  U R                      R
                  nXPR                  U R                      l        Ub,  U R                  U R                      =R                  U-  sl        U R                   U:  a  GM  ggXl         UbC  U R                  U R                      R                  U-   U R                  U R                      l        gg)a  Sets the markdown list level and indentations.

Args:
  level: int, The desired markdown list level.
  indent: int, The new indentation.
  second_line_indent: int, The second line indentation. This is subtracted
    from the prevailing indent to decrease the indentation of the next input
    line for this effect: SECOND LINE INDENT ON THE NEXT LINE PREVAILING
    INDENT ON SUBSEQUENT LINES
r   N)r=   rH   r<   rK   r*   r   r   )r   levelr   r   
prev_levelvalues         r   
_SetIndentTokenRenderer._SetIndent  s    {{U KK%[[
q;;#dll++
,,

dkkm
,LL$++f4 	T[[!( KK!OZ(;;||J'../
 ,,t{{
#
*
*a
/
*T[[)007<T[[!4)
,,t{{
#
6
6:L
L
6+ KK%0 k		' LL%88;MM 	T[[!( 
(r!   c                 0   U R                   U R                     R                  U R                  -   U l        U R                  SU R                  -  U-   [        R                  R                  5        U R                  5         U R                  5         SU l        g)zLDisplays line as an indented example.

Args:
  line: The example line text.
rG   r   N)r<   r=   r   r   r5   ru   r   r6   r7   rb   r   )r   lines     r   ExampleTokenRenderer.ExampleG  sf     dkk*11DKK?DJNN3#d*ENN,A,ABMMOLLNDJr!   c                 p   U R                  5         UR                  5        GH  nU R                  (       ds  U R                  (       d  U R                  (       d,  U R
                  U R                     R                  S-
  U l        OSU l        U R                  SU R                  -  5        U R                  R                  U5      nU R                  U R                  -
  nUS-   U:  ah  U R                  (       dW  U R                  X$4S9  U R
                  U R                     R                  U l        U R                  SU R                  -  5        O>SU l        U R                  (       a&  U =R                  S-  sl        U R                  S5        U =R                  U-  sl        U R                  U5        GM     g)zAdds a line to the output, splitting to stay within the output width.

This is close to textwrap.wrap() except that control sequence characters
don't count in the width computation.

Args:
  line: The text line.
r   r   rG   )rQ   FN)Blankr~   r5   r=   r4   r<   r   ru   r/   rN   rL   r;   rb   )r   r   rU   rY   rV   s        r   FillTokenRenderer.FillS  s(    	JJL

ZZ;;dmm||DKK077!;$*$+sTZZ'(jj%%d+e++

*i
!)		!$*<*<01\\$++.55
sTZZ'("::
**/*
..

jjEj
nnT' r!   c                 Z    U R                  5         U R                  5         U R                  $ )z'Finishes all output document rendering.)r   Fontr>   r   s    r   FinishTokenRenderer.Finishr  s    KKMIIK;;r!   c                    Uc  SU l         OSU-  nU =R                   U-  sl         U R                   S[        R                  -  S[        R                  -  -  S[        R                  -  -  -  nUS[        R                  -  -  (       a  SnOdUS[        R                  -  S[        R                  -  -  :X  a  SnO6US[        R                  -  :X  a  SnOUS[        R                  -  :X  a  SnOSnU R
                  U-   $ )zReturns the font embellishment control sequence for attr.

Args:
  attr: None to reset to the default font, otherwise one of renderer.BOLD,
    renderer.ITALIC, or renderer.CODE.

Returns:
  The font embellishment control sequence.
r   r   r   r   r   r   r   )_fontr   BOLDCODEITALICr1   )r   attrmaskfontembellishments        r   r   TokenRenderer.Fontx  s     |dj$Yd
jjDj::	
hmm	X]] 23qHOO7KLD qHMM!"m	1%!x*>?	@m	!x}}$	%m	!x&	'mm99}$$r!   c                    US:X  a  UR                  S5      (       a  gU R                  5         U R                  5         U R                  5         US:  aO  SUS-
  -  nU R	                  U5        U R
                  (       a%  SU l        U =R                  [        U5      -  sl        U R	                  U[        R                  R                  5        U R
                  (       a6  SU l        U =R                  U R                  R                  U5      -  sl        OU R                  5         U R                  5         SU l        / U l        g)zcRenders a heading.

Args:
  level: The heading level counting from 1.
  heading: The heading text.
r   z(1)Nr   z  Tr   )endswithr   Liner   ru   r4   r:   r5   rH   r   r6   re   r/   rN   rb   r   r=   rA   )r   r   headingr   s       r   HeadingTokenRenderer.Heading  s     zg&&u--KKMIIKIIKqyuqy!f
nnV	!%

c&k!
NN7ENN223}}#d
jjDJJ++G44j
mmoJJLDKDJr!   c                     U R                   (       a  gU R                  5         U R                  5       (       d!  U R                  5         U R	                  5         gg)z$Renders a paragraph separating line.N)r:   r   	HaveBlankr   rb   r   s    r   r   TokenRenderer.Line  s;    KKM>>
jjl
mmo r!   c                    U R                  5         U(       d  Xl        gU(       a  U R                  U5        gUbw  U(       aN  U R                  USSS9  U R                  SU R                  U   R
                  -  5        U R                  U5        gU R                  USSS9  U R                  5         gUS:  a  SOSnU R                  XSS9  U R                  SU R                  U   R
                  -  U R                  US-
  [        U R                  5      -     -   5        U R                  U   R                  S-   U l        S	U l        g)
zRenders a bullet or definition list item.

Args:
  level: The list nesting level, 0 if not currently in a list.
  definition: Bullet list if None, definition list item otherwise.
  end: End of list if True.
Nr      r"   rG   r   r   r   T)r   r=   r   ru   r<   r   r   r   r3   rH   r   r5   r;   )r   r   
definitionendr   s        r   ListTokenRenderer.List  s    	KKMk	
ooe			aA>sT\\%0CCCDJ'aA>		 AIq1f
ooeqoA
nn
U#66
6LL%!)s4<<'889: <<&--1djdr!   c                 j    U[        U5      :  a#  X   nUS:w  a   U$ US-  nU[        U5      :  a  M#  U$ )zSkip space characters starting at line[index].

Args:
  line: The string.
  index: The starting index in string.

Returns:
  The index in line after spaces or len(line) at end of string.
rG   r   )rH   )r   r   indexcs       r   
_SkipSpaceTokenRenderer._SkipSpace  sF     #d)

+a	
cL qje	 #d)

 Lr!   c                 V    U R                   R                  XS 5      nU(       d  SnX#-   $ )zSkip the control sequence at line[index].

Args:
  line: The string.
  index: The starting index in string.

Returns:
  The index in line after the control sequence or len(line) at end of
  string.
Nr   )r/   GetControlSequenceLen)r   r   r   ns       r   _SkipControlSequence"TokenRenderer._SkipControlSequence  s,     	

((f6A
a9r!   c                     SnU[        U5      :  aY  X   nUS-  nXc;   a  US-  nO4Xd;   a  US-  nUS::  a   U$ O X`R                  :X  a  U R                  X5      nU[        U5      :  a  MY  U$ )a*  Skip a [...] nested bracket group starting at line[index].

Args:
  line: The string.
  index: The starting index in string.
  open_chars: The open nesting characters.
  close_chars: The close nesting characters.

Returns:
  The index in line after the nesting group or len(line) at end of string.
r   r   )rH   r1   r   )r   r   r   
open_charsclose_charsnestr   s          r   	_SkipNestTokenRenderer._SkipNest  s     D
#d)

+aqje	
		19
 L	 		>))$6 #d)
 Lr!   c                 L   SnU(       Ga  S GH  nUR                  U5      u  pgnU R                  R                  U5      n	U[        U5      -   U	-   U R                  :  d  US:w  a  US:X  a  US:w  a-  X R
                  -   [        U5      -   U	-   U R                  :  a  M  US:X  a  U R                  U5        SnX2:w  a2  X R
                  -   nU R                  5         U R                  SU-  5        U R                  XF-   5        U[        U5      U	-   -  nUnUn  O   U(       a  GM  U$ )a  Splits a wide SYNOPSIS section group string._out.

Args:
  group: The wide group string to split.
  indent: The prevailing left indent.
  running_width: The width of the line in progress.

Returns:
  The running_width after the group has been split and written.
rG   )z | z : rG   ,r   )	partitionr/   rN   rH   rL   SPLIT_INDENTru   rb   )
r   rh   r   running_widthprev_delimiter	delimiterpart_	remainderws
             r   _SplitWideSynopsisGroup%TokenRenderer._SplitWideSynopsisGroup  s$    N
/)"__Y7JJ##D)S0014D$S  3---N0CCaG s"NN>* N$"%6%66MMMONN3./~,-^,q00"5 0 %: r!   c                    / nU R                  US5      nUnU[        U5      :  a  X   nUS:X  ac  UnU R                  X5      nU[        U5      S-
  ::  a(  X   S:X  a   XS-      S:X  a  U R                  XS-   5      nOTUR                  XU 5        UnO>US;   a  U R                  X5      nO&X`R                  :X  a  U R                  X5      nOUS-  nU[        U5      :  a  M  U[        U5      :  a  UR                  XS 5        U R                  S   R                  S-
  nUn	U R                  SU	-  5        XR                  -  nU H  n
U R                  R                  U
5      S-   nX-   U R                  :  aL  Un	U R                  5         U R                  SU	-  5        X-   U R                  :  a  U R                  XU	5      n	M  U R                  SU
-   5        X-  n	M     U R                  5         U R                  5         g)aG  Renders NAME and SYNOPSIS lines as a second line indent.

Collapses adjacent spaces to one space, deletes trailing space, and doesn't
split top-level nested [...] or (...) groups. Also detects and does not
count terminal control sequences.

Args:
  line: The NAME or SYNOPSIS text.
  is_synopsis: if it is the synopsis section
r   rG   r   |[(N)r   rH   rK   r   r1   r   r<   r   ru   r   r/   rN   rL   rb   r   )r   r   is_synopsisgroupsrs   begr   r   r   r   rh   r   s               r   SynopsisTokenRenderer.SynopsisD  s    Fa A
C
c$i-
'a	
cOOD$TQDGsNtE{c7IoodE*!
--
&#9NN4#		>%%d.	Q c$i-  SYmmDJ \\!_##a'FMNN3&'
kkF
**
!
!%
(1
,a

	+s]*+$++-66]- 
nnS5[!m  	MMOMMOr!   c                 R    U R                  US-  U-   5        U R                  5         g)zAdds an indented table line to the output.

Args:
  line: The line to add. A newline will be added.
  indent: The number of characters to indent the table.
rG   N)ru   rb   )r   r   r   s      r   	TableLineTokenRenderer.TableLine|  s"     	NN6C<$&'MMOr!   )r/   r3   r4   r1   r8   r5   r   r9   r:   r;   r<   r=   r>   rA   r?   r@   )r   zutf-8T)N)r   N)NF)r   z)])F)r   ),r#   r$   r%   r&   r'   r0   r   r6   BoldCodeItalicr7   
BoldItalicrr   r   r   rO   rM   objectr*   r   r[   rb   rn   ru   rJ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r(   __classcell__)rD   s   @r   r
   r
   B   s    2 	#>>>>>>  >>  >>$$. &,,v ,&-^06(+
Z
>%<:  D" 4)V6p r!   r
   )r'   
__future__r   r   r   rf   googlecloudsdk.core.consoler   &googlecloudsdk.core.document_renderersr   prompt_toolkit.tokenr   Rendererr
   r)   r!   r   <module>r      s6    %N '  ' 	 4 ; &B	H%% B	r!   