
    @                         S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKr " S S	\R                  5      rg)
z,Cloud SDK markdown document linter renderer.    )absolute_import)division)unicode_literalsN)console_attr)text_rendererc                      ^  \ rS rSrSrSrSrSrSrSr	S/r
U 4S	 jrS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r S r!S r"U =r#$ )!LinterRenderer   zBRenders markdown to a list of lines where there is a linter error.NAMEEXAMPLESDESCRIPTIONzPOSITIONAL ARGUMENTSzREQUIRED FLAGSzOPTIONAL FLAGSFLAGSzLIST COMMAND FLAGS   )meweIusheshehimher)theaan)z--quietz--helpzgcloud topicc           	        > [         [        U ]
  " U0 UD6  [        R                  " SS9U l        U R
                  R                  5       U l        S U l        U R                  U l
        [        R                  " 5       U l        [        R                  " 5       U l        U R                  U l	        U R                  U R                   U R"                  U R$                  U R$                  U R$                  U R$                  U R$                  S.U l        SU l        SU l        SU l        SU l        SU l        SU l        SU l        SU l        SU l        / U l        / U l        [>        R@                  " 5       U l!        g )Nascii)encodingr    Fr   )"superr	   __init__r   ConsoleAttr_attr
GetBullets_bullet	_csi_char_out	_file_outioStringIO	_null_out_buffer_analyze_name_analyze_examples_analyze_description_analyze_argument_sections_analyze_heading_prev_heading_example_errors_has_example_sectionexamplecommand_namename_sectioncommand_name_lengthcommand_textequals_violation_flagsnonexistent_violation_flagscollectionsOrderedDictfindings)selfargskwargs	__class__s      =lib/googlecloudsdk/core/document_renderers/linter_renderer.pyr!   LinterRenderer.__init__,   s.   	.$($9&9))7;DJ::((*DLDNYYDN[[]DN;;=DLDI!//!%!7!7$($=$=-1-L-L'+'F'F'+'F'F"==+/+J+JLDM DMD D %DDLDD DD"$D')D$++-DM    c                    U R                  5         U R                  R                  5       (       a_  U R                  (       aN  U R	                  U R                  U R                  R                  5       5        [
        R                  " 5       U l        U R                  S:X  a  U R                  5         U R                  U l        U R                  U l        g )Nr   )
check_indentation_for_examplesr,   getvaluer3   _Analyzer)   r*   check_example_section_errorsr'   r2   r@   headings     rD   _CaptureOutputLinterRenderer._CaptureOutputL   s    '')||4#5#5
mmD&&(=(=(?@[[]dlZ'
'')DIDrF   c                 &    U R                   U l        g N)r+   r'   rL   s     rD   _DiscardOutputLinterRenderer._DiscardOutputY   s    DIrF   c                 .    U R                   U   " X5        g rQ   )r1   )r@   rM   sections      rD   rJ   LinterRenderer._Analyze\   s    MM'7,rF   c                 $    SR                  X5      $ )Nz{}_{}_CHECK)format)r@   rM   checks      rD   _check_nameLinterRenderer._check_name_   s    //rF   c                 >    X R                   SR                  U5      '   g )Nz# {} FAILEDr?   rX   )r@   
check_namemessages      rD   _add_failureLinterRenderer._add_failureb   s    6=MM-&&z23rF   c                 @    SU R                   SR                  U5      '   g )Nr   z# {} SUCCESSr]   )r@   r^   s     rD   _add_successLinterRenderer._add_successe   s    79DMM.''
34rF   c                 @    SU R                   SR                  U5      '   g )Nr   z'There are no errors for the {} section.r]   rL   s     rD   _add_no_errors_summary%LinterRenderer._add_no_errors_summaryh   s$     	MM;BB rF   c                 
   U R                  5       (       a4  U R                  (       d#  U R                  U R                  SS5      S5        O3U R                  (       a"  U R
                  (       d  U R                  S5        SU l        g)zRaise violation if the examples section does not contain a valid example.

Also, wrap up the examples section by specifying there are no errors in the
section.

See go/cloud-sdk-help-text#formatting.
r   PRESENTz9You have not included an example in the Examples section.TN)needs_exampler6   r`   rZ   r5   r4   rf   r@   s    rD   rK   +LinterRenderer.check_example_section_errorsl   sc     DLL



:y
1
EG 
	"	"4+?+?
!!*-DLrF   c                     U R                  US5      nUR                  5       S   nUR                  5       U R                  ;   a%  U R	                  USR                  U5      5        SnU$ U R                  U5        SnU$ )zRaise violation if the section begins with an article.

See go/cloud-sdk-help-text#formatting.

Arguments:
  heading: str, the name of the section.
  section: str, the contents of the section.

Returns:
  True if there was a violation. False otherwise.
ARTICLESr   z3Please do not start the {} section with an article.TF)rZ   splitlower	_ARTICLESr`   rX   rc   )r@   rM   rU   r^   
first_wordfound_articles         rD   check_for_articles!LinterRenderer.check_for_articles}   s     !!':6J#JT^^+

 &34:F7OEm  
#mrF   c           	         U R                  US5      n[        [        R                  " S5      R	                  UR                  5       5      5      nUR                  U R                  5      nU(       aG  [        [        U5      5      nU R                  USR                  USR                  U5      5      5        U$ U R                  U5        U$ )z:Raise violation if the section contains personal pronouns.PRONOUNz	[\w/\-_]+zCPlease remove the following personal pronouns in the {} section:
{}
)rZ   setrecompilefindallrp   intersection_PERSONAL_PRONOUNSsortedlistr`   rX   joinrc   )r@   rM   rU   r^   words_in_sectionfound_pronounsfound_pronouns_lists          rD   check_for_personal_pronouns*LinterRenderer.check_for_personal_pronouns   s    !!'95J2::l3;;GMMOLM%2243J3JKN"4#78

 &GHN)0)-3F)GIIJ  
#rF   c                 `   U R                  US5      n[        [        R                  " S5      R	                  U5      5      n[        [        R                  " S5      R	                  U5      5      nXE:g  nU(       a#  U R                  USR                  U5      5        U$ U R                  U5        U$ )a  Raise violation if the section contains unmatched double backticks.

This check counts the number of double backticks in the section and ensures
that there are an equal number of closing double single-quotes. The common
mistake is to use a single double-quote to close these values, which breaks
the rendering. See go/cloud-sdk-help-text#formatting.

Arguments:
  heading: str, the name of the section.
  section: str, the contents of the section.

Returns:
  True if there was a violation. None otherwise.
DOUBLE_BACKTICKSz``z''zxThere are unbalanced double backticks and double single-quotes in the {} section. See go/cloud-sdk-help-text#formatting.)rZ   lenrz   r{   r|   r`   rX   rc   )r@   rM   rU   r^   double_backticks_countdouble_single_quotes_count
unbalanceds          rD   $check_for_unmatched_double_backticks3LinterRenderer.check_for_unmatched_double_backticks   s     !!'+=>J E!2!:!:7!CD!$RZZ%6%>%>w%G!H(FJ

>>DfWoP  
#rF   c                     U R                   (       a  U R                   R                  (       a  gSU R                  ;   a  gU R                   H%  nU R                  R	                  U5      (       d  M%    g   g)z*Check whether command requires an example.FalphaT)command_metadatais_groupr7   _NON_COMMAND_SURFACE_GROUPS
startswith)r@   names     rD   rj   LinterRenderer.needs_example   s^     !6!6!?!?$###00				%	%d	+	+ 1 rF   c                     U R                   S:X  aJ  U R                  R                  5       (       d*  U R                  U R	                  SS5      S5        SU l        g g g )Nr   SECTION_FORMATzThe examples section is not formatted properly. This is likely due to indentation. Please make sure the section is aligned with the heading and not indented.T)r3   r,   rI   r`   rZ   r4   rk   s    rD   rH   -LinterRenderer.check_indentation_for_examples   sY    Z'0E0E0G0G



:'7
8&'
 "d 1H'rF   c                    U R                   R                  5       (       aE  U R                  (       a4  U R                  U R                  U R                   R                  5       5        U R	                  5         U R                   R                  5         U R                  R                  5         U R                  5         U R                   H  nU R                  U   (       a[  U R                  R                  [        R                  " U5      S-   [        R                  " U R                  U   5      -   S-   5        Mr  U R                  R                  [        R                  " U5      S-   5        M     g )Nz: rx   )r,   rI   r3   rJ   rH   closer+   rK   r?   r(   writesix	text_type)r@   elements     rD   FinishLinterRenderer.Finish   s    ||4#5#5
mmD&&(=(=(?@'')LLNN%%'==	w	MM'"T)MM$--012489	: 	S]]73d:; !rF   c                 t    X l         X R                  ;   a  U R                  U5        g U R                  U5        g rQ   )r2   _HEADINGS_TO_LINTrN   rR   )r@   levelrM   s      rD   HeadingLinterRenderer.Heading   s/    M(((
'"
'"rF   c                 .   U R                   (       Ga  U R                   R                  (       Gd  U R                  S:X  Ga  U R                  (       aR  U R                  R	                  S5      (       a2  U R                  R                  S5      UR                  5       -   U l        OUR                  SS5      U l        UR	                  S5      (       Gd=  U R                  R                  U R                  5      (       Ga  SU l
        U R                  U R                  SS5      5        U R                  U R                  S  R                  5       n/ nU HF  nUR                  SS5      nUS:X  a    O-UR                  S5      (       d  M5  UR                  U5        MH     U R!                  U5        U Vs/ s H  oUR#                  S	5      S
   PM     nnU R                   (       a.  U R                   R$                  (       a  U R'                  U5        g g g g g g g g s  snf )Nr   \z$ r   Tri   z\----=r   )r   r   r2   r:   endswithrstripstripreplacer   r7   r6   rc   rZ   r9   ro   append_analyze_example_flags_equals	partitionflags_check_valid_flags)r@   linerest_of_command
flag_nameswordflagr   s          rD   ExampleLinterRenderer.Example   s    	d&;&;&D&D&D# 
		t0099$?? --44T:TZZ\I !LLr2 ]]4  ''(9(9::$,


D,,ZC
D --d.F.F.GHNNP/*%d<<-Dt|t$$% & 
,
,Z
86@Ajd>>#&q)j%A""t'<'<'B'B##E* (C" ; ! 	$ 'E4 Bs   .Hc                     U H9  nX R                   R                  ;  d  M  U R                  R                  U5        M;     g rQ   )r   r   r<   r   r@   r   r   s      rD   r   !LinterRenderer._check_valid_flags  s2    	**00	0((//5 rF   c                     U HR  nSU;  d  M  X R                   R                  ;  d  M&  X R                  ;  d  M7  U R                  R	                  U5        MT     g )Nr   )r   
bool_flags_NON_BOOL_FLAGS_ALLOWLISTr;   r   r   s      rD   r   ,LinterRenderer._analyze_example_flags_equals  sD    
T/d*?*?*J*JJ
44
4##**40 rF   c           	      \   U R                  X5      =(       d    U R                  X5      nU R                  US5      n/ nUR                  S5      nU Vs/ s H3  nUR	                  5       (       a  M  U(       d  M#  UR                  5       PM5     nnSn	U H  nU	(       a  U	R                  S5      (       d-  [        R                  " SU	R                  5       S   5      (       a]  [        U	R                  5       5      S:  a@  UR                  5       S   R                  5       U R                  ;   a  UR                  U	5        Un	M     U(       a4  SnU R                  US	R                  USR                  U5      5      5        OU R!                  U5        U(       d  U R#                  U5        g
g
s  snf )av  Raise violation if the section contains unmatched double backticks.

This check confirms that argument sections follow our help text style guide.
The help text for individual arguments should not begin with an article.
See go/cloud-sdk-help-text#formatting.

Arguments:
  heading: str, the name of the section.
  section: str, the contents of the section.

Returns:
  None.
ARG_ARTICLESrx   r   r   z[A-Z_]r      TzfPlease fix the help text for the following arguments which begin with an article in the {} section:
{}N)r   rt   rZ   ro   isspacer   r   rz   matchr   rp   rq   r   r`   rX   r   rc   rf   )
r@   rM   rU   
has_errorsr^   flags_with_articlesall_lines_in_sectionr   non_empty_lines_in_section	prev_lines
             rD   r0   )LinterRenderer._analyze_argument_sections  s}    227D <))'; !!'>:J"==.!5"*!5 	#' 	

!5  "* I*		,,T22bhh
IOO%a(7* 7*/29??3D/E/Ijjl1o##%7""9-i + j

 &FGMv)0)-3F)GHIJ 
#
!!'* )"*s   F)0F)9F)c                    U R                  X5      =(       d    U R                  X5      n[        R                  " SUR	                  5       5      nU R                  SS5      n[        U5      S:X  d'  [        U5      S:  a4  US   R	                  5       (       d  SU l        U R                  US5        SnOUS   U l        U R                  U5        U R                  SS5      nS	R                  US
   R	                  5       R                  5       5      U l        [        U R                  5      U l        [        U R                  R                  5       5      U R                  :  aB  U R                  USR                  [        R                   " U R                  5      5      5        SnOU R                  U5        U(       d  U R#                  U5        g g )Nz\s-\s?r   r      r   z*Please add an explanation for the command.TLENGTH r   zBPlease shorten the name section description to less than {} words.)r   rt   rz   ro   r   rZ   r   r8   r`   rc   r   r7   r9   _NAME_WORD_LIMITrX   r   r   rf   )r@   rM   rU   r   section_partsr^   s         rD   r-   LinterRenderer._analyze_name@  s   227D <))'; 
 HHY8M
 !!&-8J
=QMQ}Q'7'='='?'?d

DFj'*d

# !!&(3Jq!1!7!7!9!?!?!ABD"4#4#45D
4""$%(=(==


N6#-- 5 5679 j

#
!!'* rF   c                 "   SU l         U R                  X5      nU R                  R                  (       Gd  U R	                  X5      (       a  SnU R                  X5      (       a  SnU R                  US5      nU R                  (       a  SnSn[        [        U R                  5      S-
  5       H,  nU[        R                  " U R                  U   5      S-   -  nM.     U[        R                  " U R                  S   5      -  nU R                  USR                  U5      5        SnOU R                  U5        U R                  US5      nU R                  (       a  SnSn[        [        U R                  5      S-
  5       H,  nU[        R                  " U R                  U   5      S-   -  nM.     U[        R                  " U R                  S   5      -  nU R                  US	R                  U5      5        OU R                  U5        X0l        g g )
NTFLAG_EQUALSr   r   z, zVThere should be an `=` between the flag name and the value for the following flags: {}NONEXISTENT_FLAGz%The following flags are not valid: {})r5   rt   r   r   r   r   rZ   r;   ranger   r   r   r`   rX   rc   r<   r4   )r@   rM   rU   r   r^   list_contentsr   s          rD   r.    LinterRenderer._analyze_examplesf  s    $D((:J  )))		)	)'	;	;
		2	27	D	D
##G];j		$	$
#d99:Q>?D
3==))$/1378 8- @ 	t'B'B2'FGG56<f]6K	M 
*%##G-?@j		)	)
#d>>?!CDD
3==..t468<= =- E 	t'G'G'KLL3::	 
 	*%'E *rF   c                     U R                  X5      U R                  X5      U R                  X5      4n[        U5      (       d  U R	                  U5        g g rQ   )r   r   rt   anyrf   )r@   rM   rU   r   s       rD   r/   #LinterRenderer._analyze_description  sT    227D;;())';=J
 z??
!!'* rF   )r1   r#   r,   r%   r&   r4   r(   r5   r2   r+   r'   r3   r7   r9   r:   r;   r6   r?   r8   r<   )$__name__
__module____qualname____firstlineno____doc__r   r   r~   rq   r   r   r!   rN   rR   rJ   rZ   r`   rc   rf   rK   rt   r   r   rj   rH   r   r   r   r   r   r0   r-   r.   r/   __static_attributes____classcell__)rC   s   @rD   r	   r	      s    JI I ) 4!/ 0.@'-0>:".8
"<#+B6
1(+T$+L%(N+ +rF   r	   )r   
__future__r   r   r   r=   r)   rz   googlecloudsdk.core.consoler   &googlecloudsdk.core.document_renderersr   r   TextRendererr	    rF   rD   <module>r      s9     3 &  '  	 	 4 @ 
v+]// v+rF   