/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 5 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . k doc . psi . impl Ċ Ċ import Ġcom . intellij . lang . AST Node Ċ import Ġcom . intellij . openapi . util . text . StringUtil Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . TokenType Ċ import Ġorg . jetbrains . kotlin . k doc . lexer . K Doc Tokens Ċ import Ġorg . jetbrains . kotlin . k doc . parser . K Doc Element Types Ċ import Ġorg . jetbrains . kotlin . k doc . parser . K Doc Known Tag Ċ Ċ open Ġclass ĠK Doc Tag ( node : ĠAST Node ) Ġ: ĠK Doc Element Impl ( node ) Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġname Ġof Ġthis Ġtag , Ġnot Ġincluding Ġthe Ġleading Ġ@ Ġcharacter . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġtag Ġname Ġor Ġnull Ġif Ġthis Ġtag Ġrepresents Ġthe Ġdefault Ġsection Ġof Ġa Ġdoc Ġcomment ĊĠĠĠĠ Ġ* Ġor Ġthe Ġcode Ġhas Ġa Ġsyntax Ġerror . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠgetName (): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠtagName : ĠPsi Element ? Ġ= Ġfind Child ByType ( K Doc Tokens . TAG _ NAME ) ĊĠĠĠĠĠĠĠ Ġif Ġ( tagName Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠtagName . text . substring ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġname Ġof Ġthe Ġentity Ġdocumented Ġby Ġthis Ġtag Ġ( for Ġexample , Ġthe Ġname Ġof Ġthe Ġparameter ĊĠĠĠĠ Ġ* Ġfor Ġthe Ġ@ param Ġtag ), Ġor Ġnull Ġif Ġthis Ġtag Ġdoes Ġnot Ġdocument Ġany Ġspecific Ġentity . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġget Subject Name (): ĠString ? Ġ= Ġget Subject Link ()?. get Link Text () ĊĊĠĠĠ Ġfun Ġget Subject Link (): ĠK Doc Link ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchildren Ġ= Ġchildren After TagName () ĊĠĠĠĠĠĠĠ Ġif Ġ( has Subject ( children )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġchildren . first OrNull ()?. psi Ġas ? ĠK Doc Link ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġknown Tag : ĠK Doc Known Tag ? ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġname ?. let Ġ{ ĠK Doc Known Tag . findBy TagName ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Subject ( content Children : ĠList < AST Node >): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( known Tag ?. is Reference Required Ġ?: Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcontent Children . first OrNull ()?. elementType Ġ== ĠK Doc Tokens . MARK DOWN _ LINK ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchildren After TagName (): ĠList < AST Node > Ġ= ĊĠĠĠĠĠĠĠ Ġnode . getChildren ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. drop While Ġ{ Ġit . elementType Ġ== ĠK Doc Tokens . TAG _ NAME Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. drop While Ġ{ Ġit . elementType Ġ== ĠTokenType . WHITE _ SPACE Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġcontent Ġof Ġthis Ġtag Ġ( all Ġtext Ġfollowing Ġthe Ġtag Ġname Ġand Ġthe Ġsubject Ġif Ġpresent , ĊĠĠĠĠ Ġ* Ġwith Ġleading Ġaster is ks Ġremoved ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun ĠgetContent (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġval Ġcode Block Builder Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġvar Ġtarget Builder Ġ= Ġbuilder ĊĊĠĠĠĠĠĠĠ Ġvar Ġcontent Started Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġafter A ster isk Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġindent ed Code Block Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġfun Ġis Code Block () Ġ= Ġtarget Builder Ġ== Ġcode Block Builder ĊĊĠĠĠĠĠĠĠ Ġfun Ġstart Code Block () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Builder Ġ= Ġcode Block Builder ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġflush Code Block () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Code Block ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . append ( trim Common Indent ( code Block Builder , Ġindent ed Code Block )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Block Builder . set Length ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Builder Ġ= Ġbuilder ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġchildren Ġ= Ġchildren After TagName () ĊĠĠĠĠĠĠĠ Ġif Ġ( has Subject ( children )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchildren Ġ= Ġchildren . drop ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( node Ġin Ġchildren ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġnode . elementType ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠK Doc Tokens . CODE _ BLOCK _ TEXT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// If Ġfirst Ġline Ġof Ġcode Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Code Block ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindent ed Code Block Ġ= Ġindent ed Code Block Ġ|| Ġnode . text . startsWith ( indentation White Spaces ) Ġ|| Ġnode . text . startsWith ("\ t ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Code Block () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( K Doc Tokens . CONTENT _ TOKEN S . contains ( type )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflush Code Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindent ed Code Block Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( K Doc Tokens . CONTENT _ TOKEN S . contains ( type )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Plain Content Ġ= Ġafter A ster isk Ġ&& Ġ! is Code Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġcontent Ġnot Ġyet Ġstarted Ġand Ġnot Ġpart Ġof Ġindent ed Ġcode Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġand Ġnot Ġinside Ġf enced Ġcode Ġblock Ġwe Ġshould Ġtrim Ġleading Ġspaces ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtrim Leading Spaces Ġ= Ġ!( content Started Ġ|| Ġindent ed Code Block ) Ġ|| Ġis Plain Content ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Builder . append ( if Ġ( trim Leading Spaces ) Ġnode . text . trim Start () Ġelse Ġnode . text ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Started Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġafter A ster isk Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠK Doc Tokens . LEADING _ ASTER IS K ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġafter A ster isk Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠTokenType . WHITE _ SPACE Ġ&& Ġcontent Started ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Builder . append ("\ n ". repeat ( StringUtil . count New Lines ( node . text ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠK Doc Element Types . K DOC _ TAG ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġflush Code Block () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġbuilder . toString (). trim End (' Ġ', Ġ'\ t ') ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtrim Common Indent ( builder : ĠStringBuilder , Ġprepend 4 White Spaces : ĠBoolean Ġ= Ġfalse ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlines Ġ= Ġbuilder . toString (). split ('\ n ') ĊĠĠĠĠĠĠĠ Ġval Ġmin Indent Ġ= Ġlines . filter Ġ{ Ġit . trim (). isNotEmpty () Ġ}. map Ġ{ Ġit . calc Indent () Ġ}. min () Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġprocessed Lines Ġ= Ġlines . map Ġ{ Ġit . drop ( min Indent ) Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( prepend 4 White Spaces ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessed Lines Ġ= Ġprocessed Lines . map Ġ{ Ġif Ġ( it . isNotBlank ()) Ġit . prepend Indent ( indentation White Spaces ) Ġelse Ġit Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġprocessed Lines . join ToString ("\ n ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠString . calc Indent () Ġ= ĠindexOf First Ġ{ Ġ! it . is Whitespace () Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġindentation White Spaces Ġ= Ġ" Ġ". repeat ( 4 ) ĊĠĠĠ Ġ} Ċ } Ċ