package Ġjp . j ug g ler . sub way to oter . util čĊč Ċ import Ġandroid . content . Context č Ċ import Ġandroid . graphics . Color č Ċ import Ġandroid . graphics . Type face č Ċ import Ġandroid . text . Sp ann able StringBuilder č Ċ import Ġandroid . text . Sp anned č Ċ import Ġandroid . text . style . BackgroundColor Span č Ċ import Ġandroid . text . style . ForegroundColor Span č Ċ import Ġandroid . text . style . Relative Size Span č Ċ import Ġandroid . text . style . Stri ke through Span č Ċ import Ġandroid . util . Sparse Array č Ċ import Ġandroid . util . Sparse Boolean Array č Ċ import Ġjp . j ug g ler . sub way to oter . Act Main č Ċ import Ġjp . j ug g ler . sub way to oter . R č Ċ import Ġjp . j ug g ler . sub way to oter . api . entity . To ot Account č Ċ import Ġjp . j ug g ler . sub way to oter . api . entity . To ot Mention č Ċ import Ġjp . j ug g ler . sub way to oter . span .* č Ċ import Ġjp . j ug g ler . sub way to oter . table . Highlight Word č Ċ import Ġjp . j ug g ler . util . Log Category č Ċ import Ġjp . j ug g ler . util . encode Percent č Ċ import Ġjp . j ug g ler . util . font Span č Ċ import Ġjp . j ug g ler . util . short en Url č Ċ import Ġjava . util .* č Ċ import Ġjava . util . regex . Matcher č Ċ import Ġjava . util . regex . Pattern čĊč Ċ private Ġval Ġbrackets Ġ= ĠarrayOf ( čĊ ĉ " ()", čĊ ĉ " ()", čĊ ĉ " [] ", čĊ ĉ " {}", čĊ ĉ " âĢľ âĢĿ ", čĊ ĉ " âĢĺ âĢĻ ", čĊ ĉ " âĢ ¹ âĢ º ", čĊ ĉ " Â « Â» ", čĊ ĉ " ï¼Ī ï¼ī ", čĊ ĉ " ï¼ » ï¼ ½ ", čĊ ĉ " ï½ Ľ ï½ Ŀ ", čĊ ĉ " ï½ Ł ï½ ł ", čĊ ĉ " â ¦ ħ â ¦ Ĩ ", čĊ ĉ " ãĢ ļ ãĢ Ľ ", čĊ ĉ " â ¦ ĥ â ¦ Ħ ", čĊ ĉ " ãĢĮ ãĢį ", čĊ ĉ " ãĢ Ī ãĢ ī ", čĊ ĉ " ãĢĬ ãĢĭ ", čĊ ĉ " ãĢĲ ãĢĳ ", čĊ ĉ " ãĢ Ķ ãĢ ķ ", čĊ ĉ " â ¦ Ĺ â ¦ ĺ ", čĊ ĉ " ãĢ İ ãĢ ı ", čĊ ĉ " ãĢ ĸ ãĢ Ĺ ", čĊ ĉ " ãĢ ĺ ãĢ Ļ ", čĊ ĉ " [] ", čĊ ĉ " ï½ ¢ ï½ £ ", čĊ ĉ " âŁ ¦ âŁ § ", čĊ ĉ " âŁ ¨ âŁ © ", čĊ ĉ " âŁ ª âŁ « ", čĊ ĉ " âŁ ® âŁ ¯ ", čĊ ĉ " âŁ ¬ âŁ Ń ", čĊ ĉ " â Į Ī â Į ī ", čĊ ĉ " â Į Ĭ â Į ĭ ", čĊ ĉ " â ¦ ĩ â ¦ Ī ", čĊ ĉ " â ¦ ī â ¦ Ĭ ", čĊ ĉ " âĿ Ľ âĿ ľ ", čĊ ĉ " âĿ Ŀ âĿ ŀ ", čĊ ĉ " âĿ ¨ âĿ © ", čĊ ĉ " âĿ ª âĿ « ", čĊ ĉ " âĿ ´ âĿ µ ", čĊ ĉ " âĿ ¬ âĿ Ń ", čĊ ĉ " âĿ ® âĿ ¯ ", čĊ ĉ " âĿ ° âĿ ± ", čĊ ĉ " âĿ ² âĿ ³ ", čĊ ĉ " ()", čĊ ĉ " ï ´ ¾ ï ´ ¿ ", čĊ ĉ " â Į © â Į ª ", čĊ ĉ " â ¦ ĳ â ¦ Ĵ ", čĊ ĉ " â § ¼ â § ½ ", čĊ ĉ " ï ¹ Ļ ï ¹ ļ ", čĊ ĉ " ï ¹ Ľ ï ¹ ľ ", čĊ ĉ " ï ¹ Ŀ ï ¹ ŀ ", čĊ ĉ " âģ ½ âģ ¾ ", čĊ ĉ " âĤ į âĤ İ ", čĊ ĉ " â ¦ ĭ â ¦ Į ", čĊ ĉ " â ¦ į â ¦ İ ", čĊ ĉ " â ¦ ı â ¦ Ĳ ", čĊ ĉ " âģ ħ âģ Ĩ ", čĊ ĉ " â ¸ ¢ â ¸ £ ", čĊ ĉ " â ¸ ¤ â ¸ ¥ ", čĊ ĉ " âŁ ħ âŁ Ĩ ", čĊ ĉ " â ¦ ĵ â ¦ Ķ ", čĊ ĉ " â ¦ ķ â ¦ ĸ ", čĊ ĉ " â ¸ ¦ â ¸ § ", čĊ ĉ " â ¸ ¨ â ¸ © ", čĊ ĉ " â § ĺ â § Ļ ", čĊ ĉ " â § ļ â § Ľ ", čĊ ĉ " â ¸ ľ â ¸ Ŀ ", čĊ ĉ " â ¸ Į â ¸ į ", čĊ ĉ " â ¸ Ĥ â ¸ ĥ ", čĊ ĉ " â ¸ Ħ â ¸ ħ ", čĊ ĉ " â ¸ ī â ¸ Ĭ ", čĊ ĉ " áļ Ľ áļ ľ ", čĊ ĉ " à ¼ º à ¼ » ", čĊ ĉ " à ¼ ¼ à ¼ ½ ", čĊ ĉ " â ı ľ â ı Ŀ ", čĊ ĉ " â İ ´ â İ µ ", čĊ ĉ " â ı ŀ â ı Ł ", čĊ ĉ " â ı ł â ı ¡ ", čĊ ĉ " ï ¹ ģ ï ¹ Ĥ ", čĊ ĉ " ï ¹ ĥ ï ¹Ħ ", čĊ ĉ " ï¸ ¹ ï¸ º ", čĊ ĉ " ï¸ » ï¸ ¼ ", čĊ ĉ " ï¸ Ĺ ï¸ ĺ ", čĊ ĉ " ï¸ ¿ ï ¹ Ģ ", čĊ ĉ " ï¸ ½ ï¸ ¾ ", čĊ ĉ " ï ¹ ĩ ï ¹ Ī ", čĊ ĉ " ï¸ · ï¸ ¸ " č Ċ ) čĊč Ċ private Ġval Ġbrackets Map Ġ= ĠHashMap < Char , ĠInt >(). apply Ġ{ čĊ ĉ br ackets . forEach Ġ{ čĊĉ ĉ put ( it [ 0 ], Ġ 1 ) čĊĉ ĉ put ( it [ 1 ], Ġ- Ġ 1 ) čĊ ĉ } č Ċ } č Ċ private Ġval Ġbrackets Map Url Safe Ġ= ĠHashMap < Char , ĠInt >(). apply Ġ{ čĊ ĉ br ackets . forEach Ġ{ čĊĉ ĉ if ( Ġ"( [" . contains ( it [ 0 ]) Ġ) Ġreturn @ forEach čĊĉ ĉ put ( it [ 0 ], Ġ 1 ) čĊĉ ĉ put ( it [ 1 ], Ġ- Ġ 1 ) čĊ ĉ } č Ċ } čĊč Ċ // Ġ æľ« å°¾ ãģ® ä½Ļ è¨Ī ãģª ãĢį ãĤĦ ï¼Ī ãĤĴ åıĸ ãĤĬ éĻ¤ ãģı ãĢĤ č Ċ // Ġ ä¾ĭ ãģĪ ãģ° ãĢĮ # ãĤ¿ ãĤ° ãĢį Ġãģ¨ ãģĭ Ġï¼Ī # ãĤ¿ ãĤ° ï¼ī č Ċ fun ĠString . remove Or phan ed Br ackets ( url Safe : Boolean Ġ= false ) Ġ: ĠString Ġ{ čĊ ĉ var Ġlast Ġ= Ġ 0 čĊ ĉ val Ġn ests Ġ= Ġwhen ( url Safe ){ čĊĉ ĉ true -> this . map Ġ{ čĊĉĉ ĉ last Ġ+= Ġbrackets Map Url Safe [ it ] Ġ?: Ġ 0 čĊĉĉ ĉ last čĊĉ ĉ } čĊĉ ĉ else -> this . map Ġ{ čĊĉĉĉčĊĉĉ ĉ last Ġ+= Ġbrackets Map [ it ] Ġ?: Ġ 0 čĊĉĉ ĉ last čĊĉ ĉ } čĊ ĉ } čĊčĊ ĉ // Ġfirst Ġposition Ġof Ġun matched Ġclose čĊ ĉ var Ġpos Ġ= Ġn ests . indexOf First Ġ{ Ġit Ġ< Ġ 0 Ġ} čĊ ĉ if ( pos Ġ!= Ġ- Ġ 1 ) Ġreturn Ġsubstring ( 0 , Ġpos ) čĊčĊ ĉ // Ġlast Ġposition Ġof Ġun matched Ġopen čĊ ĉ pos Ġ= Ġn ests . indexOf Last Ġ{ Ġit Ġ== Ġ 0 Ġ} čĊ ĉ return Ġsubstring ( 0 , Ġpos Ġ+ Ġ 1 ) č Ċ } čĊč Ċ // Ġ éħį åĪĹ ä¸Ń ãģ® è¦ģ ç´ł ãĤĴ ãĥ© ãĥł ãĥĢ å¼ı ãģ§ å¤ī æıĽ ãģĹãģ¦ ãĢģ æĪ » ãĤĬ åĢ¤ ãģĮ éĿŀ null ãģª ãĤī ãģĿ ãģĵ ãģ§ åĩ¦çĲĨ ãĤĴ æīĵ ãģ¡ åĪĩ ãĤĭ č Ċ private Ġinline Ġfun Ġ< T , ĠV > ĠArray < out ĠT >. first NonNull ( predicate Ġ: Ġ( T ) Ġ-> ĠV ?) Ġ: ĠV ? Ġ{ čĊ ĉ for ( element Ġin Ġthis ) Ġreturn Ġpredicate ( element ) Ġ?: Ġcontinue čĊ ĉ return Ġnull č Ċ } čĊč Ċ // Ġ æĸĩåŃĹ è£ħ é£ ¾ ãģ® æĮĩå®ļ ãĤĴ æº ľ ãĤģ ãģ¦ ãģĬ ãģĦãģ¦ ãĥİ ãĥ¼ãĥī ãģ® è¦ ª åŃĲ éĸ¢ ä¿ Ĥ ãģ« å¿ľ ãģĺ ãģ¦ éłĨ åºı ãĤĴ èª¿ æķ´ ãģĹãģ¦ ãĢģ æľĢ å¾Į ãģ« ãģ¾ ãģ¨ ãĤģ ãģ¦ éģ© çĶ¨ ãģĻãĤĭ č Ċ class ĠSpan List Ġ{ čĊĉčĊ ĉ private Ġclass ĠSpan Pos ( var Ġstart Ġ: ĠInt , Ġvar Ġend Ġ: ĠInt , Ġval Ġspan Ġ: ĠAny ) čĊĉčĊ ĉ private Ġval Ġlist Ġ= ĠLinkedList < Span Pos >() čĊĉčĊ ĉ fun Ġset Span ( sb Ġ: ĠSp ann able StringBuilder ) Ġ= čĊĉ ĉ list . forEach Ġ{ Ġsb . set Span ( it . span , Ġit . start , Ġit . end , ĠSp anned . SPAN _ EXCL USIVE _ EXCL USIVE ) Ġ} čĊĉčĊ ĉ fun Ġadd All ( other Ġ: ĠSpan List ) Ġ= Ġlist . addAll ( other . list ) čĊĉčĊ ĉ fun Ġadd With Offset ( src Ġ: ĠSpan List , Ġoffset Ġ: ĠInt ) Ġ{ čĊĉ ĉ src . list . forEach Ġ{ Ġadd Last ( it . start Ġ+ Ġoffset , Ġit . end Ġ+ Ġoffset , Ġit . span ) Ġ} čĊ ĉ } čĊĉčĊ ĉ fun Ġadd First ( start Ġ: ĠInt , Ġend Ġ: ĠInt , Ġspan Ġ: ĠAny ) Ġ= Ġwhen Ġ{ čĊĉ ĉ start Ġ== Ġend Ġ-> Ġ{ čĊĉĉ ĉ // Ġempty Ġspan Ġallowed čĊĉ ĉ } čĊĉĉčĊĉ ĉ start Ġ> Ġend Ġ-> Ġ{ čĊĉĉ ĉ Miss key Markdown Decoder . log . e (" Span List . add : Ġrange Ġerror ! Ġstart =$ start , end =$ end , span =$ span ") čĊĉ ĉ } čĊĉĉčĊĉ ĉ else Ġ-> Ġ{ čĊĉĉ ĉ list . add First ( Span Pos ( start , Ġend , Ġspan )) čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ fun Ġadd Last ( start Ġ: ĠInt , Ġend Ġ: ĠInt , Ġspan Ġ: ĠAny ) Ġ= Ġwhen Ġ{ čĊĉ ĉ start Ġ== Ġend Ġ-> Ġ{ čĊĉĉ ĉ // Ġempty Ġspan Ġallowed čĊĉ ĉ } čĊĉĉčĊĉ ĉ start Ġ> Ġend Ġ-> Ġ{ čĊĉĉ ĉ Miss key Markdown Decoder . log . e (" Span List . add : Ġrange Ġerror ! Ġstart =$ start , end =$ end , span =$ span ") čĊĉ ĉ } čĊĉĉčĊĉ ĉ else Ġ-> Ġ{ čĊĉĉ ĉ list . add Last ( Span Pos ( start , Ġend , Ġspan )) čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ fun Ġinsert ( offset Ġ: ĠInt , Ġlength Ġ: ĠInt ) Ġ{ čĊĉ ĉ for ( sp Ġin Ġlist ) Ġ{ čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ sp . end Ġ<= Ġoffset Ġ-> Ġ{ čĊĉĉĉĉčĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ sp . start Ġ<= Ġoffset Ġ-> Ġ{ čĊĉĉĉĉ ĉ sp . end Ġ+= Ġlength čĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġ{ čĊĉĉĉĉ ĉ sp . start Ġ+= Ġlength čĊĉĉĉĉ ĉ sp . end Ġ+= Ġlength čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉĉčĊĉ ĉ } čĊ ĉ } čĊĉč Ċ } čĊč Ċ // Ġ æŃ£ è¦ı è¡¨ çı¾ ãĥĳ ãĤ¿ ãĥ¼ãĥ³ ãģĶ ãģ¨ ãģ« Matcher ãĤĴ ãĤŃ ãĥ£ ãĥĥ ãĤ·ãĥ¥ ãģĻãĤĭ č Ċ // Ġ å¯¾è±¡ ãĥĨ ãĤŃ ãĤ¹ãĥĪ ãģĮ å¤ī ãĤı ãģ£ãģŁ ãĤī ãĤŃ ãĥ£ ãĥĥ ãĤ·ãĥ¥ ãĤĴ æį ¨ ãģ¦ ãģ¦ æĽ´æĸ° ãģĻãĤĭ č Ċ // ĠMatcher # region ( start , text . length ) ĠãĤĴ è¨Ńå®ļ ãģĹãģ¦ ãģĭãĤī è¿Ķ ãģĻ č Ċ // Ġ( åĲĮ ä¸Ģ ãĥĨ ãĤŃ ãĤ¹ãĥĪ ãģ«å¯¾ ãģĹãģ¦ Matcher . use Pattern ãģ§ æŃ£ è¦ı è¡¨ çı¾ ãĥĳ ãĤ¿ ãĥ¼ãĥ³ ãĤĴ åĪĩ ãĤĬ æĽ¿ ãģĪãĤĭ ãģ® ãĤĤ æ¤ľ è¨ İ ãģĹãģŁ ãģĮ ãĢģ use Pattern ãģ® æĸ¹ ãģĮ å¤ļ åĪĨ éģ ħ ãģı ãģªãĤĭ ) č Ċ internal Ġobject ĠMatcher Cache Ġ{ čĊĉčĊ ĉ private Ġclass ĠMatcher Cache Item ( čĊĉ ĉ var Ġmatcher Ġ: ĠMatcher , čĊĉ ĉ var Ġtext Ġ: ĠString , čĊĉ ĉ var Ġtext HashCode Ġ: ĠInt čĊ ĉ ) čĊĉčĊ ĉ // Ġ ãĤ¹ ãĥ¬ ãĥĥãĥī ãģĶ ãģ¨ ãģ« ãĤŃ ãĥ£ ãĥĥ ãĤ·ãĥ¥ çĶ¨ ãģ® ãĥŀ ãĥĥãĥĹ ãĤĴ æĮģ ãģ¤ čĊ ĉ private Ġval Ġmatcher Cache Ġ= čĊĉ ĉ object Ġ: ĠThread Local < HashMap < Pattern , ĠMatcher Cache Item >>() Ġ{ čĊĉĉ ĉ override Ġfun Ġinitial Value () Ġ: ĠHashMap < Pattern , ĠMatcher Cache Item > Ġ= ĠHashMap () čĊĉ ĉ } čĊĉčĊ ĉ internal Ġfun Ġmatcher ( čĊĉ ĉ pattern Ġ: ĠPattern , čĊĉ ĉ text Ġ: ĠString , čĊĉ ĉ start Ġ: ĠInt Ġ= Ġ 0 , čĊĉ ĉ end Ġ: ĠInt Ġ= Ġtext . length čĊ ĉ ) Ġ: ĠMatcher Ġ{ čĊĉ ĉ val Ġm Ġ: ĠMatcher čĊĉ ĉ val Ġtext HashCode Ġ= Ġtext . hashCode () čĊĉ ĉ val Ġmap Ġ= Ġmatcher Cache . get () Ġ!! čĊĉ ĉ val Ġitem Ġ= Ġmap [ pattern ] čĊĉ ĉ if ( item Ġ!= Ġnull ) Ġ{ čĊĉĉ ĉ if ( item . text HashCode Ġ!= Ġtext HashCode Ġ|| Ġitem . text Ġ!= Ġtext ) Ġ{ čĊĉĉĉ ĉ item . matcher Ġ= Ġpattern . matcher ( text ). apply Ġ{ čĊĉĉĉĉ ĉ use Anchor ing Bounds ( true ) čĊĉĉĉ ĉ } čĊĉĉĉ ĉ item . text Ġ= Ġtext čĊĉĉĉ ĉ item . text HashCode Ġ= Ġtext HashCode čĊĉĉ ĉ } čĊĉĉ ĉ m Ġ= Ġitem . matcher čĊĉ ĉ } Ġelse Ġ{ čĊĉĉ ĉ m Ġ= Ġpattern . matcher ( text ). apply Ġ{ čĊĉĉĉ ĉ use Anchor ing Bounds ( true ) čĊĉĉ ĉ } čĊĉĉ ĉ map [ pattern ] Ġ= ĠMatcher Cache Item ( m , Ġtext , Ġtext HashCode ) čĊĉ ĉ } čĊĉ ĉ m . region ( start , Ġend ) čĊĉ ĉ return Ġm čĊ ĉ } č Ċ } čĊč Ċ // Ġ``` code ``` Ġãĥ ŀ ãĥ¼ãĤ¯ ãĥĢ ãĤ¦ ãĥ³ åĨħéĥ¨ ãģ§ãģ¯ ãĥĹãĥŃãĤ°ãĥ©ãĥł ãģ£ ãģ ½ ãģĦ ä½ķ ãģĭ ãģ® æĸĩ æ³ķ å¼ · èª¿ è¡¨ç¤º ãģĮ è¡Į ãĤı ãĤĮãĤĭ č Ċ object ĠM iss key Syntax Highlight er Ġ{ čĊĉčĊ ĉ private Ġval Ġkeywords Ġ= ĠHashSet < String >(). apply Ġ{ čĊĉĉčĊĉ ĉ val Ġ_ keywords Ġ= ĠarrayOf ( čĊĉĉ ĉ " true ", čĊĉĉ ĉ " false ", čĊĉĉ ĉ " null ", čĊĉĉ ĉ " nil ", čĊĉĉ ĉ " undefined ", čĊĉĉ ĉ " void ", čĊĉĉ ĉ " var ", čĊĉĉ ĉ " const ", čĊĉĉ ĉ " let ", čĊĉĉ ĉ " mut ", čĊĉĉ ĉ " dim ", čĊĉĉ ĉ " if ", čĊĉĉ ĉ " then ", čĊĉĉ ĉ " else ", čĊĉĉ ĉ " switch ", čĊĉĉ ĉ " match ", čĊĉĉ ĉ " case ", čĊĉĉ ĉ " default ", čĊĉĉ ĉ " for ", čĊĉĉ ĉ " each ", čĊĉĉ ĉ " in ", čĊĉĉ ĉ " while ", čĊĉĉ ĉ " loop ", čĊĉĉ ĉ " continue ", čĊĉĉ ĉ " break ", čĊĉĉ ĉ " do ", čĊĉĉ ĉ " goto ", čĊĉĉ ĉ " next ", čĊĉĉ ĉ " end ", čĊĉĉ ĉ " sub ", čĊĉĉ ĉ " throw ", čĊĉĉ ĉ " try ", čĊĉĉ ĉ " catch ", čĊĉĉ ĉ " finally ", čĊĉĉ ĉ " enum ", čĊĉĉ ĉ " delegate ", čĊĉĉ ĉ " function ", čĊĉĉ ĉ " func ", čĊĉĉ ĉ " fun ", čĊĉĉ ĉ " fn ", čĊĉĉ ĉ " return ", čĊĉĉ ĉ " yield ", čĊĉĉ ĉ " async ", čĊĉĉ ĉ " await ", čĊĉĉ ĉ " require ", čĊĉĉ ĉ " include ", čĊĉĉ ĉ " import ", čĊĉĉ ĉ " imports ", čĊĉĉ ĉ " export ", čĊĉĉ ĉ " exports ", čĊĉĉ ĉ " from ", čĊĉĉ ĉ " as ", čĊĉĉ ĉ " using ", čĊĉĉ ĉ " use ", čĊĉĉ ĉ " internal ", čĊĉĉ ĉ " module ", čĊĉĉ ĉ " namespace ", čĊĉĉ ĉ " where ", čĊĉĉ ĉ " select ", čĊĉĉ ĉ " struct ", čĊĉĉ ĉ " union ", čĊĉĉ ĉ " new ", čĊĉĉ ĉ " delete ", čĊĉĉ ĉ " this ", čĊĉĉ ĉ " super ", čĊĉĉ ĉ " base ", čĊĉĉ ĉ " class ", čĊĉĉ ĉ " interface ", čĊĉĉ ĉ " abstract ", čĊĉĉ ĉ " static ", čĊĉĉ ĉ " public ", čĊĉĉ ĉ " private ", čĊĉĉ ĉ " protected ", čĊĉĉ ĉ " virtual ", čĊĉĉ ĉ " partial ", čĊĉĉ ĉ " override ", čĊĉĉ ĉ " extends ", čĊĉĉ ĉ " implements ", čĊĉĉ ĉ " constructor " čĊĉ ĉ ) čĊĉĉčĊĉ ĉ // Ġlower čĊĉ ĉ addAll (_ keywords ) čĊĉĉčĊĉ ĉ // ĠUPPER čĊĉ ĉ addAll (_ keywords . map Ġ{ Ġk Ġ-> Ġk . toUpperCase () Ġ}) čĊĉĉčĊĉ ĉ // ĠSn ake čĊĉ ĉ addAll (_ keywords . map Ġ{ Ġk Ġ-> Ġk [ 0 ]. toUpperCase () Ġ+ Ġk . substring ( 1 ) Ġ}) čĊĉĉčĊĉ ĉ add (" NaN ") čĊĉĉčĊĉ ĉ // Ġ èŃ ĺ åĪ¥ åŃĲ ãģ«å¯¾ ãģĹãģ¦ æĹ¢ åŃĺ ãģ® åĲįåīį ãģ¨ ä¸Ģèĩ´ ãģĻãĤĭ ãģĭ èª¿ ãģ¹ ãĤĭ ãĤĪãģĨãģ« ãģª ãģ£ãģŁ ãģ®ãģ§ ãĢģ ãĤĤ ãģ¯ ãĤĦ ãĤ½ ãĥ¼ãĥĪ ãģ® å¿ħè¦ģ ãģ¯ ãģªãģĦ čĊ ĉ } čĊĉčĊ ĉ private Ġval Ġsymbol Map Ġ= ĠSparse Boolean Array (). apply Ġ{ čĊĉ ĉ " = +- */ % ~ ^ & | >< ! ? ". forEach Ġ{ Ġput ( it . toInt (), Ġtrue ) Ġ} čĊ ĉ } čĊĉčĊ ĉ // Ġ æĸĩåŃĹåĪĹ ãĥª ãĥĨ ãĥ© ãĥ«ãģ® éĸĭå§ĭ æĸĩåŃĹ ãģ® ãĥŀ ãĥĥãĥĹ čĊ ĉ private Ġval Ġstring Start Ġ= ĠSparse Boolean Array (). apply Ġ{ čĊĉ ĉ " \" '` ". forEach Ġ{ Ġput ( it . toInt (), Ġtrue ) Ġ} čĊ ĉ } čĊĉčĊ ĉ private Ġclass ĠToken ( čĊĉ ĉ val Ġlength Ġ: ĠInt , čĊĉ ĉ val Ġcolor Ġ: ĠInt Ġ= Ġ 0 , čĊĉ ĉ val Ġitalic Ġ: ĠBoolean Ġ= Ġfalse , čĊĉ ĉ val Ġcomment Ġ: ĠBoolean Ġ= Ġfalse čĊ ĉ ) čĊĉčĊ ĉ private Ġclass ĠEnv ( čĊĉ ĉ val Ġsource Ġ: ĠString , čĊĉ ĉ val Ġstart Ġ: ĠInt , čĊĉ ĉ val Ġend Ġ: ĠInt čĊ ĉ ) Ġ{ čĊĉĉčĊĉ ĉ // Ġ åĩºåĬĽ åħĪ 2 čĊĉ ĉ val Ġspan List Ġ= ĠSpan List () čĊĉĉčĊĉ ĉ fun Ġpush ( start Ġ: ĠInt , Ġtoken Ġ: ĠToken ) Ġ{ čĊĉĉ ĉ val Ġend Ġ= Ġstart Ġ+ Ġtoken . length čĊĉĉĉčĊĉĉ ĉ if ( token . comment ) Ġ{ čĊĉĉĉ ĉ span List . add Last ( start , Ġend , ĠFore ground Color Span ( Color . BLACK Ġor Ġ 0 x 8 0 8 0 0 0 )) čĊĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉ ĉ var Ġc Ġ= Ġtoken . color čĊĉĉĉ ĉ if ( c Ġ!= Ġ 0 ) Ġ{ čĊĉĉĉĉ ĉ if ( c Ġ< Ġ 0 x 1 0 0 0 0 0 0 ) Ġ{ čĊĉĉĉĉĉ ĉ c Ġ= Ġc Ġor ĠColor . BLACK čĊĉĉĉĉ ĉ } čĊĉĉĉĉ ĉ span List . add Last ( start , Ġend , ĠFore ground Color Span ( c )) čĊĉĉĉ ĉ } čĊĉĉĉ ĉ if ( token . italic ) Ġ{ čĊĉĉĉĉ ĉ span List . add Last ( čĊĉĉĉĉĉ ĉ start , čĊĉĉĉĉĉ ĉ end , čĊĉĉĉĉĉ ĉ font Span ( Type face . default From Style ( Type face . ITAL IC )) čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ // Ġ ãĤ¹ ãĤŃ ãĥ£ ãĥ³ ä½įç½® čĊĉ ĉ var Ġpos Ġ: ĠInt Ġ= Ġstart čĊĉĉčĊĉ ĉ fun Ġremain Matcher ( pattern Ġ: ĠPattern ) Ġ: ĠMatcher Ġ= čĊĉĉ ĉ Matcher Cache . matcher ( pattern , Ġsource , Ġpos , Ġend ) čĊĉĉčĊĉ ĉ fun Ġparse () Ġ: ĠSpan List Ġ{ čĊĉĉĉčĊĉĉ ĉ var Ġi Ġ= Ġstart čĊĉĉĉčĊĉĉ ĉ var Ġlast End Ġ= Ġstart čĊĉĉ ĉ fun Ġclose Text Token ( text End Ġ: ĠInt ) Ġ{ čĊĉĉĉ ĉ val Ġlength Ġ= Ġtext End Ġ- Ġlast End čĊĉĉĉ ĉ if ( length Ġ> Ġ 0 ) Ġ{ čĊĉĉĉĉ ĉ push ( last End , ĠToken ( length Ġ= Ġlength )) čĊĉĉĉĉ ĉ last End Ġ= Ġtext End čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ while ( i Ġ< Ġend ) Ġ{ čĊĉĉĉ ĉ pos Ġ= Ġi čĊĉĉĉ ĉ val Ġtoken Ġ= Ġelements . first NonNull Ġ{ čĊĉĉĉĉ ĉ val Ġt Ġ= Ġthis . it () čĊĉĉĉĉ ĉ when Ġ{ čĊĉĉĉĉĉ ĉ t Ġ== Ġnull Ġ-> Ġnull Ġ// Ġnot Ġmatch čĊĉĉĉĉĉ ĉ i Ġ+ Ġt . length Ġ> Ġend Ġ-> Ġnull Ġ// Ġover run Ġdetected čĊĉĉĉĉĉ ĉ else Ġ-> Ġt čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉĉ ĉ if ( token Ġ== Ġnull ) Ġ{ čĊĉĉĉĉ ĉ ++ Ġi čĊĉĉĉĉ ĉ continue čĊĉĉĉ ĉ } čĊĉĉĉ ĉ close Text Token ( i ) čĊĉĉĉ ĉ push ( i , Ġtoken ) čĊĉĉĉ ĉ i Ġ+= Ġtoken . length čĊĉĉĉ ĉ last End Ġ= Ġi čĊĉĉ ĉ } čĊĉĉ ĉ close Text Token ( end ) čĊĉĉĉčĊĉĉ ĉ return Ġspan List čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ private Ġval Ġre Line Comment Ġ= ĠPattern . compile (""" \ A // .* """) čĊ ĉ private Ġval Ġre Block Comment Ġ= ĠPattern . compile (""" \ A /\ * .* ?\ */ """, ĠPattern . DOT ALL ) čĊ ĉ private Ġval Ġre Number Ġ= ĠPattern . compile (""" \ A [ \- + ]? [\ d . ]+ """) čĊ ĉ private Ġval Ġre Label Ġ= ĠPattern . compile (""" \ A @ ([ A - Z _- ][ A - Z 0 - 9 _- ]*) """, ĠPattern . CASE _ INS ENS ITIVE ) čĊ ĉ private Ġval Ġre Keyword Ġ= čĊĉ ĉ Pattern . compile (""" \ A ([ A - Z _- ][ A - Z 0 - 9 _- ]*) ([ Ġ\ t ]* \ ()? """, ĠPattern . CASE _ INS ENS ITIVE ) čĊ ĉ private Ġval Ġre Contains Alpha Ġ= ĠPattern . compile (""" [ A - Za - z _] """) čĊĉčĊ ĉ private Ġconst Ġval Ġchar H 8 0 Ġ= Ġ 0 x 8 0 . to Char () čĊĉčĊ ĉ private Ġval Ġelements Ġ= ĠarrayOf < Env . () Ġ-> ĠToken ? >( čĊĉĉčĊĉ ĉ // Ġãĥ ŀ ãĥ« ãĥģ ãĥĲ ãĤ¤ãĥĪ æĸĩåŃĹ ãĤĴ ãģ¾ ãģ¨ ãĤģ ãģ¦ èªŃãģ¿ é£ Ľ ãģ° ãģĻ čĊĉ ĉ { čĊĉĉ ĉ var Ġs Ġ= Ġpos čĊĉĉ ĉ while ( s Ġ< Ġend Ġ&& Ġsource [ s ] Ġ>= Ġchar H 8 0 ) Ġ{ čĊĉĉĉ ĉ ++ Ġs čĊĉĉ ĉ } čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ s Ġ> Ġpos Ġ-> ĠToken ( length Ġ= Ġs Ġ- Ġpos ) čĊĉĉĉ ĉ else Ġ-> Ġnull čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġ ç©º çĻ½ ãģ¨ æĶ¹ è¡Į ãĤĴ ãģ¾ ãģ¨ ãĤģ ãģ¦ èªŃãģ¿ é£ Ľ ãģ° ãģĻ čĊĉ ĉ { čĊĉĉ ĉ var Ġs Ġ= Ġpos čĊĉĉ ĉ while ( s Ġ< Ġend Ġ&& Ġsource [ s ] Ġ<= Ġ' Ġ') Ġ{ čĊĉĉĉ ĉ ++ Ġs čĊĉĉ ĉ } čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ s Ġ> Ġpos Ġ-> ĠToken ( length Ġ= Ġs Ġ- Ġpos ) čĊĉĉĉ ĉ else Ġ-> Ġnull čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġcomment čĊĉ ĉ { čĊĉĉ ĉ val Ġmatch Ġ= Ġremain Matcher ( re Line Comment ) čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatch . find () Ġ-> Ġnull čĊĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġmatch . end () Ġ- Ġmatch . start (), Ġcomment Ġ= Ġtrue ) čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġblock Ġcomment čĊĉ ĉ { čĊĉĉ ĉ val Ġmatch Ġ= Ġremain Matcher ( re Block Comment ) čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatch . find () Ġ-> Ġnull čĊĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġmatch . end () Ġ- Ġmatch . start (), Ġcomment Ġ= Ġtrue ) čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġstring čĊĉ ĉ { čĊĉĉ ĉ val Ġbegin Char Ġ= Ġsource [ pos ] čĊĉĉ ĉ if (! Ġstring Start [ begin Char . toInt ()]) Ġreturn @ array Of Ġnull čĊĉĉ ĉ var Ġi Ġ= Ġpos Ġ+ Ġ 1 čĊĉĉ ĉ while ( i Ġ< Ġend ) Ġ{ čĊĉĉĉ ĉ val Ġchar Ġ= Ġsource [ i Ġ++ ] čĊĉĉĉ ĉ if ( char Ġ== Ġbegin Char ) Ġ{ čĊĉĉĉĉ ĉ break Ġ// Ġend čĊĉĉĉ ĉ } Ġelse Ġif ( char Ġ== Ġ'\ n ' Ġ|| Ġi Ġ>= Ġend ) Ġ{ čĊĉĉĉĉ ĉ i Ġ= Ġ 0 Ġ// Ġnot Ġstring Ġliteral čĊĉĉĉĉ ĉ break čĊĉĉĉ ĉ } Ġelse Ġif ( char Ġ== Ġ'\\ ' Ġ&& Ġi Ġ< Ġend ) Ġ{ čĊĉĉĉĉ ĉ ++ Ġi Ġ// Ġ\" Ġ ãģ§ãģ¯ éĸ ī ãģĺ ãģªãģĦ ãĤĪãģĨãģ« ãģĻãĤĭ čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ i Ġ<= Ġpos Ġ-> Ġnull čĊĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġi Ġ- Ġpos , Ġcolor Ġ= Ġ 0 xe 9 6 9 0 0 ) čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġregexp čĊĉ ĉ { čĊĉĉ ĉ if ( source [ pos ] Ġ!= Ġ'/') Ġreturn @ array Of Ġnull čĊĉĉ ĉ val Ġregexp Ġ= ĠStringBuilder () čĊĉĉ ĉ var Ġi Ġ= Ġpos Ġ+ Ġ 1 čĊĉĉ ĉ while ( i Ġ< Ġend ) Ġ{ čĊĉĉĉ ĉ val Ġchar Ġ= Ġsource [ i Ġ++ ] čĊĉĉĉ ĉ if ( char Ġ== Ġ'/') Ġ{ čĊĉĉĉĉ ĉ break čĊĉĉĉ ĉ } Ġelse Ġif ( char Ġ== Ġ'\ n ' Ġ|| Ġi Ġ>= Ġend ) Ġ{ čĊĉĉĉĉ ĉ i Ġ= Ġ 0 Ġ// Ġnot Ġclosed čĊĉĉĉĉ ĉ break čĊĉĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉĉ ĉ regexp . append ( char ) čĊĉĉĉĉ ĉ if ( char Ġ== Ġ'\\ ' Ġ&& Ġi Ġ< Ġend ) Ġ{ čĊĉĉĉĉĉ ĉ regexp . append ( source [ i Ġ++ ]) čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ i Ġ== Ġ 0 Ġ-> Ġnull čĊĉĉĉ ĉ regexp . isEmpty () Ġ-> Ġnull čĊĉĉĉ ĉ regexp . first () Ġ== Ġ' Ġ' Ġ&& Ġregexp . last () Ġ== Ġ' Ġ' Ġ-> Ġnull čĊĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġregexp . length Ġ+ Ġ 2 , Ġcolor Ġ= Ġ 0 xe 9 0 0 3 f ) čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġlabel čĊĉ ĉ { čĊĉĉ ĉ // Ġ çĽ´ åīį ãģ« èŃ ĺ åĪ¥ åŃĲ ãģĮãģĤ ãĤĮãģ° NG čĊĉĉ ĉ val Ġprev Ġ= Ġif ( pos Ġ<= Ġ 0 ) Ġnull Ġelse Ġsource [ pos Ġ- Ġ 1 ] čĊĉĉ ĉ if ( prev ?. is Letter Or Digit () Ġ== Ġtrue ) Ġreturn @ array Of Ġnull čĊĉĉĉčĊĉĉ ĉ val Ġmatch Ġ= Ġremain Matcher ( re Label ) čĊĉĉ ĉ if (! Ġmatch . find ()) Ġreturn @ array Of Ġnull čĊĉĉĉčĊĉĉ ĉ val Ġmatch End Ġ= Ġmatch . end () čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ // Ġ@ user @ host Ġãģ® ãĤĪãģĨãģ« çĽ´ å¾Į ãģ« @ ãģĮ ç¶ļ ãģı ãģ® ãģ¯ NG čĊĉĉĉ ĉ match End Ġ< Ġend Ġ&& Ġsource [ match End ] Ġ== Ġ'@ ' Ġ-> Ġnull čĊĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġmatch . end () Ġ- Ġpos , Ġcolor Ġ= Ġ 0 xe 9 0 0 3 f ) čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġnumber čĊĉ ĉ { čĊĉĉ ĉ val Ġprev Ġ= Ġif ( pos Ġ<= Ġ 0 ) Ġnull Ġelse Ġsource [ pos Ġ- Ġ 1 ] čĊĉĉ ĉ if ( prev ?. is Letter Or Digit () Ġ== Ġtrue ) Ġreturn @ array Of Ġnull čĊĉĉ ĉ val Ġmatch Ġ= Ġremain Matcher ( re Number ) čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatch . find () Ġ-> Ġnull čĊĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġmatch . end () Ġ- Ġpos , Ġcolor Ġ= Ġ 0 xae 8 1 ff ) čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġmethod , Ġproperty , Ġkeyword čĊĉ ĉ { čĊĉĉ ĉ // Ġ çĽ´ åīį ãģ® æĸĩåŃĹ ãģĮ èŃ ĺ åĪ¥ åŃĲ ãģ« ä½¿ ãģĪãĤĭ ãģª ãĤī èŃ ĺ åĪ¥ åŃĲ ãģ® éĸĭå§ĭ ãģ¨ ãģ¯ ãģ¿ ãģª ãģķ ãģªãģĦ čĊĉĉ ĉ val Ġprev Ġ= Ġif ( pos Ġ<= Ġ 0 ) Ġnull Ġelse Ġsource [ pos Ġ- Ġ 1 ] čĊĉĉ ĉ if ( prev ?. is Letter Or Digit () Ġ== Ġtrue Ġ|| Ġprev Ġ== Ġ'_ ') Ġreturn @ array Of Ġnull čĊĉĉĉčĊĉĉ ĉ val Ġmatch Ġ= Ġremain Matcher ( re Keyword ) čĊĉĉ ĉ if (! Ġmatch . find ()) Ġreturn @ array Of Ġnull čĊĉĉ ĉ val Ġkw Ġ= Ġmatch . group ( 1 ) čĊĉĉ ĉ val Ġbracket Ġ= Ġmatch . group ( 2 ) čĊĉĉĉčĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ // Ġ èĭ± æķ°åŃĹ ãĤĦ _ ãĤĴ åĲ« ãģ¾ ãģªãģĦ ãĤŃ ãĥ¼ãĥ ¯ ãĥ¼ãĥī ãģ¯ çĦ¡ è¦ĸ ãģĻãĤĭ čĊĉĉĉ ĉ // Ġ- moz - foo - ĠãĤ Ħ Ġ__ Ġãģ¯ ãĤŃ ãĥ¼ãĥ ¯ ãĥ¼ãĥī ãģł ãģĮ ãĢģ Ġ- ĠãĤ Ħ Ġ-- Ġãģ¯ ãĤŃ ãĥ¼ãĥ ¯ ãĥ¼ãĥī ãģ§ãģ¯ ãģªãģĦ čĊĉĉĉ ĉ ! Ġre Contains Alpha . matcher ( kw ). find () Ġ-> Ġnull čĊĉĉĉĉčĊĉĉĉ ĉ // Ġãĥ¡ ãĤ½ãĥĥãĥī åĳ¼ ãģ³ åĩº ãģĹãģ ¯ å¯¾è±¡ ãģĮ å¤īæķ° ãģĭ ãĥĹãĥŃ ãĥĳ ãĥĨãĤ£ ãģĭ ãģ«éĸ¢ ãĤı ãĤī ãģļ ãĥ¡ ãĤ½ãĥĥãĥī ãģ® èī² ãģ« ãģªãĤĭ čĊĉĉĉ ĉ bracket ?. isNotEmpty () Ġ== Ġtrue Ġ-> čĊĉĉĉĉ ĉ Token ( length Ġ= Ġkw . length , Ġcolor Ġ= Ġ 0 x 8 9 6 4 c 1 , Ġitalic Ġ= Ġtrue ) čĊĉĉĉĉčĊĉĉĉ ĉ // Ġ å¤īæķ° ãĤĦ å®ļ æķ° ãģ§ãģ¯ ãģªãģı ãĥĹãĥŃ ãĥĳ ãĥĨãĤ£ ãģª ãĤī ãĥĹãĥŃ ãĥĳ ãĥĨãĤ£ ãģ® èī² ãģ« ãģªãĤĭ čĊĉĉĉ ĉ prev Ġ== Ġ'.' Ġ-> ĠToken ( length Ġ= Ġkw . length , Ġcolor Ġ= Ġ 0 xa 7 1 d 5 d ) čĊĉĉĉĉčĊĉĉĉ ĉ // Ġ äºĪ ç´Ħ èªŀ ãģ§ãģ¯ ãģªãģĦ čĊĉĉĉ ĉ // Ġ å¼ · èª¿ è¡¨ç¤º ãģĹãģªãģĦ ãģĮ ãĢģ èŃ ĺ åĪ¥ åŃĲ åįĺ ä½į ãģ§ èªŃãģ¿ é£ Ľ ãģ° ãģĻ čĊĉĉĉ ĉ ! Ġkeywords . contains ( kw ) Ġ-> ĠToken ( length Ġ= Ġkw . length ) čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġwhen ( kw ) Ġ{ čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ // Ġ å®ļ æķ° čĊĉĉĉĉ ĉ " true ", Ġ" false ", Ġ" null ", Ġ" nil ", Ġ" undefined ", Ġ" NaN " Ġ-> čĊĉĉĉĉĉ ĉ Token ( length Ġ= Ġkw . length , Ġcolor Ġ= Ġ 0 xae 8 1 ff ) čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ // Ġ ãģĿãģ® ä»ĸ ãģ® äºĪ ç´Ħ èªŀ čĊĉĉĉĉ ĉ else Ġ-> ĠToken ( length Ġ= Ġkw . length , Ġcolor Ġ= Ġ 0 x 2 9 7 3 b 7 ) čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ }, čĊĉĉčĊĉ ĉ // Ġsymbol čĊĉ ĉ { čĊĉĉ ĉ val Ġc Ġ= Ġsource [ pos ] čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ symbol Map . get ( c . toInt (), Ġfalse ) Ġ-> čĊĉĉĉĉ ĉ Token ( length Ġ= Ġ 1 , Ġcolor Ġ= Ġ 0 x 4 2 b 9 8 3 ) čĊĉĉĉ ĉ c Ġ== Ġ'-' Ġ-> čĊĉĉĉĉ ĉ Token ( length Ġ= Ġ 1 , Ġcolor Ġ= Ġ 0 x 4 2 b 9 8 3 ) čĊĉĉĉ ĉ else Ġ-> Ġnull čĊĉĉ ĉ } čĊĉ ĉ } čĊ ĉ ) čĊĉčĊ ĉ fun Ġparse ( source Ġ: ĠString ) Ġ= ĠEnv ( source , Ġ 0 , Ġsource . length ). parse () č Ċ } čĊč Ċ object ĠM iss key Markdown Decoder Ġ{ čĊĉčĊ ĉ internal Ġval Ġlog Ġ= ĠLog Category (" Miss key Markdown Decoder ") čĊĉčĊ ĉ internal Ġconst Ġval ĠDEBUG Ġ= Ġfalse čĊĉčĊ ĉ // Ġãĥĩ ãĤ³ãĥ¼ãĥī çµĲæŀľ ãģ«ãģ¯ ãĥ¡ ãĥ³ ãĤ·ãĥ§ãĥ³ ãģ® éħį åĪĹ ãĤĴ åĲ« ãĤĢ ãĢĤ To ot Status ãģ® ãĥĳ ãĥ¼ãĤ µ ãģĮ ãģĵãĤĮ ãĤĴ åĽŀ åı İ ãģĻãĤĭ ãĢĤ čĊ ĉ class ĠSp ann able StringBuilder Ex ( čĊĉ ĉ var Ġmentions Ġ: ĠArrayList < To ot Mention >? Ġ= Ġnull čĊ ĉ ) Ġ: ĠSp ann able StringBuilder () čĊĉčĊ ĉ // Ġãĥ ĸ ãĥŃ ãĥĥãĤ¯ è¦ģ ç´ł ãģ¯ å§ĭ ç«¯ ãģ¨ çµĤ ç«¯ ãģ® ç©º è¡Į ãĤĴ éĻ¤ åİ» ãģĹãģŁ ãģĦ čĊ ĉ private Ġval Ġre Start Empty Lines Ġ= Ġ""" \ A (?: [ Ġ ãĢĢ ]* ? [\ x 0 d \ x 0 a ]+ )+ """. to Regex () čĊ ĉ private Ġval Ġre End Empty Lines Ġ= Ġ""" [\ s \ x 0 d \ x 0 a ]+ \ z """. to Regex () čĊ ĉ private Ġfun Ġtrim Block ( s Ġ: ĠString ) Ġ= čĊĉ ĉ s . replace ( re Start Empty Lines , Ġ"") čĊĉĉ ĉ . replace ( re End Empty Lines , Ġ"") čĊĉčĊ ĉ // Ġ è£ħ é£ ¾ ãģ¤ ãģį ãĥĨ ãĤŃ ãĤ¹ãĥĪ ãģ® åĩºåĬĽ æĻĤ ãģ« ä½¿ ãģĨ ãĥĩãĥ¼ãĤ¿ ãģ® éĽĨ ãģ¾ ãĤĬ čĊ ĉ internal Ġclass ĠSpan Output Env ( čĊĉ ĉ val Ġoptions Ġ: ĠDecode Options , čĊĉ ĉ val Ġsb Ġ: ĠSp ann able StringBuilder Ex čĊ ĉ ) Ġ{ čĊĉĉčĊĉ ĉ val Ġcontext Ġ: ĠContext Ġ= Ġoptions . context Ġ?: Ġerror (" missing Ġcontext ") čĊĉ ĉ val Ġfont _ bold Ġ= ĠAct Main . timeline _ font _ bold čĊĉ ĉ val Ġlink Helper Ġ: ĠLink Helper ? Ġ= Ġoptions . link Helper čĊĉ ĉ var Ġspan List Ġ= ĠSpan List () čĊĉĉčĊĉ ĉ var Ġstart Ġ= Ġ 0 čĊĉĉčĊĉ ĉ fun Ġprepare Ment ions () Ġ: ĠArrayList < To ot Mention > Ġ{ čĊĉĉ ĉ var Ġmentions Ġ= Ġsb . mentions čĊĉĉ ĉ if ( mentions Ġ!= Ġnull ) Ġreturn Ġmentions čĊĉĉ ĉ mentions Ġ= ĠArrayList () čĊĉĉ ĉ sb . mentions Ġ= Ġmentions čĊĉĉ ĉ return Ġmentions čĊĉ ĉ } čĊĉĉčĊĉ ĉ fun Ġfire Render ( node Ġ: ĠNode ) Ġ: ĠSpan List Ġ{ čĊĉĉ ĉ val Ġspan List Ġ= ĠSpan List () čĊĉĉ ĉ this . span List Ġ= Ġspan List čĊĉĉ ĉ this . start Ġ= Ġsb . length čĊĉĉ ĉ val Ġrender Ġ= Ġnode . type . render čĊĉĉ ĉ this . render ( node ) čĊĉĉ ĉ return Ġspan List čĊĉ ĉ } čĊĉĉčĊĉ ĉ internal Ġfun Ġfire Render Child Nodes ( parent Ġ: ĠNode ) Ġ: ĠSpan List Ġ{ čĊĉĉ ĉ val Ġparent _ result Ġ= Ġthis . span List čĊĉĉ ĉ parent . childNodes . forEach Ġ{ čĊĉĉĉ ĉ val Ġchild _ result Ġ= Ġfire Render ( it ) čĊĉĉĉ ĉ parent _ result . addAll ( child _ result ) čĊĉĉ ĉ } čĊĉĉ ĉ this . span List Ġ= Ġparent _ result čĊĉĉ ĉ return Ġparent _ result čĊĉ ĉ } čĊĉĉčĊĉ ĉ // Ġ çĽ´ åīį ãģ® æĸĩåŃĹ ãģĮ æĶ¹ è¡Į æĸĩåŃĹ ãģ§ ãģª ãģĳ ãĤĮãģ° æĶ¹ è¡Į ãģĻãĤĭ čĊĉ ĉ fun Ġclose Previous Block () Ġ{ čĊĉĉ ĉ if ( start Ġ> Ġ 0 Ġ&& Ġsb [ start Ġ- Ġ 1 ] Ġ!= Ġ'\ n ') Ġ{ čĊĉĉĉ ĉ sb . append ('\ n ') čĊĉĉĉ ĉ start Ġ= Ġsb . length čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ fun Ġclose Block () Ġ{ čĊĉĉ ĉ if ( sb . length Ġ> Ġ 0 Ġ&& Ġsb [ sb . length Ġ- Ġ 1 ] Ġ!= Ġ'\ n ') Ġ{ čĊĉĉĉ ĉ val Ġstart Ġ= Ġsb . length čĊĉĉĉ ĉ sb . append ('\ n ') čĊĉĉĉ ĉ val Ġend Ġ= Ġsb . length čĊĉĉĉ ĉ sb . set Span ( Relative Size Span ( 0 . 1 f ), Ġstart , Ġend , ĠSp anned . SPAN _ EXCL USIVE _ EXCL USIVE ) čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ private Ġfun Ġapply Highlight ( start Ġ: ĠInt , Ġend Ġ: ĠInt ) Ġ{ čĊĉĉ ĉ val Ġlist Ġ= Ġoptions . highlight T rie ?. match List ( sb , Ġstart , Ġend ) čĊĉĉ ĉ if ( list Ġ!= Ġnull ) Ġ{ čĊĉĉĉ ĉ for ( range Ġin Ġlist ) Ġ{ čĊĉĉĉĉ ĉ val Ġword Ġ= ĠHighlight Word . load ( range . word ) čĊĉĉĉĉ ĉ if ( word Ġ!= Ġnull ) Ġ{ čĊĉĉĉĉĉ ĉ options . has Highlight Ġ= Ġtrue čĊĉĉĉĉĉ ĉ span List . add Last ( čĊĉĉĉĉĉĉ ĉ range . start , čĊĉĉĉĉĉĉ ĉ range . end , čĊĉĉĉĉĉĉ ĉ Highlight Span ( word . color _ fg , Ġword . color _ bg ) čĊĉĉĉĉĉ ĉ ) čĊĉĉĉĉĉ ĉ if ( word . sound _ type Ġ!= ĠHighlight Word . SOUND _ TYPE _ NONE ) Ġ{ čĊĉĉĉĉĉĉ ĉ options . highlight _ sound Ġ= Ġword čĊĉĉĉĉĉ ĉ } čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ // Ġãĥ Ĩ ãĤŃ ãĤ¹ãĥĪ ãĤĴ è¿½åĬł ãģĻãĤĭ čĊĉ ĉ fun Ġappend Text ( text Ġ: ĠString , Ġdecode Emoji Ġ: ĠBoolean Ġ= Ġfalse ) Ġ{ čĊĉĉ ĉ val Ġstart Ġ= Ġsb . length čĊĉĉ ĉ if ( decode Emoji ) Ġ{ čĊĉĉĉ ĉ sb . append ( options . decode Emoji ( text )) čĊĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉ ĉ sb . append ( text ) čĊĉĉ ĉ } čĊĉĉ ĉ apply Highlight ( start , Ġsb . length ) čĊĉ ĉ } čĊĉĉčĊĉ ĉ // ĠURL ä¸Ń ãģ® ãĥĨ ãĤŃ ãĤ¹ãĥĪ ãĤĴ è¿½åĬł ãģĻãĤĭ čĊĉ ĉ private Ġfun Ġappend Link Text ( display _ url Ġ: ĠString , Ġhref Ġ: ĠString ) Ġ{ čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ // Ġæ· » ä»ĺ ãĥ¡ ãĥĩãĤ£ ãĤ¢ ãģ® URL ãģª ãĤī çµ µ æĸĩåŃĹ ãģ« å¤ī ãģĪ ãģ¦ ãģĹãģ¾ ãģĨ čĊĉĉĉ ĉ options . is Media Attachment ( href ) Ġ-> Ġ{ čĊĉĉĉĉ ĉ // Ġ ãĥª ãĥ³ ãĤ¯ ãģ® ä¸Ģ éĥ¨ ãģ« çµ µ æĸĩåŃĹ ãģĮãģĤãĤĭ åł´åĲĪ ãĢģ çµ µ æĸĩåŃĹ ãĤ¹ ãĥĳ ãĥ³ ãĤĴ ãĤ»ãĥĥãĥĪ ãģĹãģ¦ ãģĭãĤī ãĥª ãĥ³ ãĤ¯ ãĤĴ ãĤ»ãĥĥãĥĪ ãģĻãĤĭ čĊĉĉĉĉ ĉ val Ġstart Ġ= Ġsb . length čĊĉĉĉĉ ĉ sb . append ( href ) čĊĉĉĉĉ ĉ span List . add First ( čĊĉĉĉĉĉ ĉ start , čĊĉĉĉĉĉ ĉ sb . length , čĊĉĉĉĉĉ ĉ Emoji Image Span ( context , ĠR . drawable . em j _ 1 f 5 bc _ fe 0 f ) čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġappend Text ( short en Url ( display _ url )) čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ // Ġ ãĥª ãĥ³ ãĤ¯ ãĤĴ è¿½åĬł ãģĻãĤĭ čĊĉ ĉ fun Ġappend Link ( text Ġ: ĠString , Ġurl Ġ: ĠString , Ġallow Short Ġ: ĠBoolean Ġ= Ġfalse ) Ġ{ čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ allow Short Ġ-> Ġappend Link Text ( text , Ġurl ) čĊĉĉĉ ĉ else Ġ-> Ġappend Text ( text ) čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ val Ġlink Helper Ġ= Ġoptions . link Helper čĊĉĉ ĉ if ( link Helper Ġ!= Ġnull ) Ġ{ čĊĉĉĉ ĉ // Ġ ãĥª ãĥ³ ãĤ¯ ãģ® ä¸Ģ éĥ¨ ãģ« ãĥı ãĤ¤ ãĥ©ãĤ¤ ãĥĪ ãģĮãģĤãĤĭ åł´åĲĪ ãĢģ ãĥª ãĥ³ ãĤ¯ ãĤĴ ãĤ»ãĥĥãĥĪ ãģĹãģ¦ ãģĭãĤī ãĥı ãĤ¤ ãĥ©ãĤ¤ ãĥĪ ãĤĴ ãĤ»ãĥĥãĥĪ ãģĹãģªãģĦ ãģ¨ ãĤ¯ãĥªãĥĥãĤ¯ åĪ¤ å®ļ ãģĮ ãģĬ ãģĭ ãģĹãģ ı ãģªãĤĭ ãĢĤ čĊĉĉĉ ĉ span List . add First ( čĊĉĉĉĉ ĉ start , Ġsb . length , ĠMy Clickable Span ( čĊĉĉĉĉĉ ĉ text čĊĉĉĉĉĉ ĉ , Ġurl čĊĉĉĉĉĉ ĉ , Ġlink Helper . find Ac ct Color ( url ) čĊĉĉĉĉĉ ĉ , Ġoptions . link Tag čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ ) čĊĉĉ ĉ } čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ //////////////////////////////////////////////////////////////////////////// čĊĉčĊ ĉ private Ġfun Ġmix Color ( col 1 Ġ: ĠInt , Ġcol 2 Ġ: ĠInt ) Ġ: ĠInt Ġ= ĠColor . rgb ( čĊĉ ĉ ( Color . red ( col 1 ) Ġ+ ĠColor . red ( col 2 )) Ġ ush r Ġ 1 , čĊĉ ĉ ( Color . green ( col 1 ) Ġ+ ĠColor . green ( col 2 )) Ġ ush r Ġ 1 , čĊĉ ĉ ( Color . blue ( col 1 ) Ġ+ ĠColor . blue ( col 2 )) Ġ ush r Ġ 1 čĊ ĉ ) čĊĉčĊ ĉ val Ġquote Nest Colors Ġ= Ġint ArrayOf ( čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 x 0 0 0 0 ff ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 x 0 0 8 0 ff ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 x 0 0 ff 8 0 ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 x 0 0 ff 0 0 ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 x 8 0 ff 0 0 ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 xff 8 0 0 0 ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 xff 0 0 0 0 ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 xff 0 0 8 0 ), čĊĉ ĉ mix Color ( Color . GRAY , Ġ 0 x 8 0 0 0 ff ) čĊ ĉ ) čĊĉčĊ ĉ // Ġãĥ İ ãĥ¼ãĥī ç¨® åĪ¥ ãģ¨ ãĥ¬ ãĥ³ ãĥĢ ãĥª ãĥ³ãĤ° éĸ¢æķ° čĊ ĉ internal Ġenum Ġclass ĠNode Type ( val Ġrender Ġ: ĠSpan Output Env .( Node ) Ġ-> ĠUnit ) Ġ{ čĊĉĉčĊĉ ĉ TEXT ({ čĊĉĉ ĉ append Text ( it . args [ 0 ], Ġdecode Emoji Ġ= Ġtrue ) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ E MO JI ({ čĊĉĉ ĉ val Ġcode Ġ= Ġit . args [ 0 ] čĊĉĉ ĉ if ( code . isNotEmpty ()) Ġ{ čĊĉĉĉ ĉ append Text (" :$ code :", Ġdecode Emoji Ġ= Ġtrue ) čĊĉĉ ĉ } čĊĉ ĉ }), čĊĉĉčĊĉ ĉ MENT ION ({ čĊĉĉ ĉ val Ġusername Ġ= Ġit . args [ 0 ] čĊĉĉ ĉ val Ġhost Ġ= Ġit . args [ 1 ] čĊĉĉ ĉ val Ġlink Helper Ġ= Ġlink Helper čĊĉĉ ĉ if ( link Helper Ġ== Ġnull ) Ġ{ čĊĉĉĉ ĉ append Text ( čĊĉĉĉĉ ĉ when Ġ{ čĊĉĉĉĉĉ ĉ host . isEmpty () Ġ-> Ġ"@ $ username " čĊĉĉĉĉĉ ĉ else Ġ-> Ġ"@ $ username @ $ host " čĊĉĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ ) čĊĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉĉčĊĉĉĉ ĉ val Ġuser Host Ġ= Ġwhen Ġ{ čĊĉĉĉĉ ĉ host . isEmpty () Ġ-> Ġlink Helper . host čĊĉĉĉĉ ĉ else Ġ-> Ġhost čĊĉĉĉ ĉ } Ġ?: Ġ" ?" čĊĉĉĉĉčĊĉĉĉ ĉ when ( user Host . toLowerCase ()) Ġ{ čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ // Ġhttps :// github . com / sy ui lo / miss key / pull / 3 6 0 3 čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ " github . com ", Ġ" twitter . com " Ġ-> Ġ{ čĊĉĉĉĉĉ ĉ append Link ( čĊĉĉĉĉĉĉ ĉ " @ $ username @ $ user Host ", čĊĉĉĉĉĉĉ ĉ " https :// $ user Host /$ username " Ġ// Ġno Ġ@ čĊĉĉĉĉĉ ĉ ) čĊĉĉĉĉ ĉ } čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ " gmail . com " Ġ-> Ġ{ čĊĉĉĉĉĉ ĉ append Link ( čĊĉĉĉĉĉĉ ĉ " @ $ username @ $ user Host ", čĊĉĉĉĉĉĉ ĉ " mailto :$ username @ $ user Host " čĊĉĉĉĉĉ ĉ ) čĊĉĉĉĉ ĉ } čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ else Ġ-> Ġ{ čĊĉĉĉĉĉ ĉ val Ġuser Url Ġ= Ġ" https :// $ user Host /@ $ username " čĊĉĉĉĉĉĉ čĊĉĉĉĉĉ ĉ val Ġshort Ac ct Ġ= Ġwhen Ġ{ čĊĉĉĉĉĉĉ ĉ host . isEmpty () čĊĉĉĉĉĉĉĉ ĉ || Ġhost . equals ( link Helper . host , Ġignore Case Ġ= Ġtrue ) Ġ-> čĊĉĉĉĉĉĉĉ ĉ username čĊĉĉĉĉĉĉ ĉ else Ġ-> čĊĉĉĉĉĉĉĉ ĉ "$ username @ $ host " čĊĉĉĉĉĉ ĉ } čĊĉĉĉĉĉĉ čĊĉĉĉĉĉ ĉ val Ġmentions Ġ= Ġprepare Ment ions () čĊĉĉĉĉĉĉ čĊĉĉĉĉĉ ĉ if ( mentions . find Ġ{ Ġm Ġ-> Ġm . acct Ġ== Ġshort Ac ct Ġ} Ġ== Ġnull ) Ġ{ čĊĉĉĉĉĉĉ ĉ mentions . add ( čĊĉĉĉĉĉĉĉ ĉ To ot Mention ( čĊĉĉĉĉĉĉĉĉ ĉ jp . j ug g ler . sub way to oter . api . entity . EntityId . DEFAULT čĊĉĉĉĉĉĉĉĉ ĉ , Ġuser Url čĊĉĉĉĉĉĉĉĉ ĉ , Ġshort Ac ct čĊĉĉĉĉĉĉĉĉ ĉ , Ġusername čĊĉĉĉĉĉĉĉ ĉ ) čĊĉĉĉĉĉĉ ĉ ) čĊĉĉĉĉĉ ĉ } čĊĉĉĉĉĉĉ čĊĉĉĉĉĉ ĉ append Link ( čĊĉĉĉĉĉĉ ĉ when Ġ{ čĊĉĉĉĉĉĉĉ ĉ jp . j ug g ler . sub way to oter . Pref . bp Mention Full Ac ct ( jp . j ug g ler . sub way to oter . App 1 . pref ) Ġ-> Ġ"@ $ username @ $ user Host " čĊĉĉĉĉĉĉĉ ĉ else Ġ-> Ġ"@ $ short Ac ct " čĊĉĉĉĉĉĉ ĉ } čĊĉĉĉĉĉĉ ĉ , Ġuser Url čĊĉĉĉĉĉ ĉ ) čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ }), čĊĉĉčĊĉ ĉ HAS HT AG ({ čĊĉĉ ĉ val Ġlink Helper Ġ= Ġlink Helper čĊĉĉ ĉ val Ġtag Ġ= Ġit . args [ 0 ] čĊĉĉ ĉ if ( tag . isNotEmpty () Ġ&& Ġlink Helper Ġ!= Ġnull ) Ġ{ čĊĉĉĉ ĉ append Link ( čĊĉĉĉĉ ĉ " #$ tag ", čĊĉĉĉĉ ĉ " https ://${ link Helper . host }/ tags /" Ġ+ Ġtag . encode Percent () čĊĉĉĉ ĉ ) čĊĉĉ ĉ } čĊĉ ĉ }), čĊĉĉčĊĉ ĉ CODE _ INLINE ({ čĊĉĉ ĉ val Ġtext Ġ= Ġit . args [ 0 ] čĊĉĉ ĉ val Ġsp Ġ= ĠM iss key Syntax Highlight er . parse ( text ) čĊĉĉ ĉ append Text ( text ) čĊĉĉ ĉ span List . add With Offset ( sp , Ġstart ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , ĠBackground Color Span ( 0 x 4 0 8 0 8 0 8 0 )) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , Ġfont Span ( Type face . MON O SPACE )) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ URL ({ čĊĉĉ ĉ val Ġurl Ġ= Ġit . args [ 0 ] čĊĉĉ ĉ if ( url . isNotEmpty ()) Ġ{ čĊĉĉĉ ĉ append Link ( url , Ġurl , Ġallow Short Ġ= Ġtrue ) čĊĉĉ ĉ } čĊĉ ĉ }), čĊĉĉčĊĉ ĉ CODE _ BLOCK ({ čĊĉĉ ĉ close Previous Block () čĊĉĉĉčĊĉĉ ĉ val Ġtext Ġ= Ġtrim Block ( it . args [ 0 ]) čĊĉĉ ĉ val Ġsp Ġ= ĠM iss key Syntax Highlight er . parse ( text ) čĊĉĉ ĉ append Text ( text ) čĊĉĉ ĉ span List . add With Offset ( sp , Ġstart ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , ĠBackground Color Span ( 0 x 4 0 8 0 8 0 8 0 )) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , Ġandroid . text . style . Relative Size Span ( 0 . 7 f )) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , Ġfont Span ( Type face . MON O SPACE )) čĊĉĉ ĉ close Block () čĊĉ ĉ }), čĊĉĉčĊĉ ĉ QUOTE _ INLINE ({ čĊĉĉ ĉ val Ġtext Ġ= Ġtrim Block ( it . args [ 0 ]) čĊĉĉ ĉ append Text ( text ) čĊĉĉ ĉ span List . add Last ( čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ sb . length , čĊĉĉĉ ĉ android . text . style . BackgroundColor Span ( 0 x 2 0 8 0 8 0 8 0 ) čĊĉĉ ĉ ) čĊĉĉ ĉ span List . add Last ( čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ sb . length , čĊĉĉĉ ĉ font Span ( android . graphics . Type face . default From Style ( android . graphics . Type face . ITAL IC )) čĊĉĉ ĉ ) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ SEARCH ({ čĊĉĉ ĉ close Previous Block () čĊĉĉĉčĊĉĉ ĉ val Ġtext Ġ= Ġit . args [ 0 ] čĊĉĉ ĉ val Ġkw _ start Ġ= Ġsb . length Ġ// ĠãĤ Ń ãĥ¼ãĥ ¯ ãĥ¼ãĥī ãģ® éĸĭå§ĭ ä½įç½® čĊĉĉ ĉ append Text ( text ) čĊĉĉ ĉ append Text (" Ġ") čĊĉĉ ĉ start Ġ= Ġsb . length Ġ// Ġæ ¤ ľç´¢ ãĥª ãĥ³ ãĤ¯ ãģ® éĸĭå§ĭ ä½įç½® čĊĉĉĉčĊĉĉ ĉ append Link ( čĊĉĉĉ ĉ context . getString ( R . string . search ), čĊĉĉĉ ĉ " https :// www . google . co . jp / search ? q =${ text . encode Percent () }" čĊĉĉ ĉ ) čĊĉĉ ĉ span List . add Last ( kw _ start , Ġsb . length , ĠRelative Size Span ( 1 . 2 f )) čĊĉĉĉčĊĉĉ ĉ close Block () čĊĉ ĉ }), čĊĉĉčĊĉ ĉ BIG ({ čĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , ĠM iss key Big Span ( font _ bold )) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ BOLD ({ čĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , Ġfont Span ( font _ bold )) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ STRI KE ({ čĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , ĠStri ke through Span ()) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ SMALL ({ čĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , ĠRelative Size Span ( 0 . 7 f )) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ ITAL IC ({ čĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , Ġfont Span ( Type face . default From Style ( Type face . ITAL IC ))) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ MOT ION ({ čĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ span List . add First ( čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ sb . length , čĊĉĉĉ ĉ Miss key Motion Span ( Act Main . timeline _ font ) čĊĉĉ ĉ ) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ LINK ({ čĊĉĉ ĉ val Ġurl Ġ= Ġit . args [ 1 ] čĊĉĉ ĉ // Ġval Ġsilent Ġ= Ġdata ?. get ( 2 ) čĊĉĉ ĉ // Ġsilent ãģ¯ ãĥĹ ãĥ¬ ãĥĵ ãĥ¥ ãĥ¼ è¡¨ç¤º ãĤĴ æĬ ĳ åĪ¶ ãģĻãĤĭ ãģĮ ãĢģ Sub way ãģ«ãģ¯ ãĤĤ ãģ¨ ãĤĤ ãģ¨ ãģªãģĦ ãģ®ãģ§ éĸ¢ ä¿ Ĥ ãģª ãģĭ ãģ£ãģŁ čĊĉĉĉčĊĉĉ ĉ if ( url . isNotEmpty ()) Ġ{ čĊĉĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉĉ ĉ val Ġlink Helper Ġ= Ġoptions . link Helper čĊĉĉĉ ĉ if ( link Helper Ġ!= Ġnull ) Ġ{ čĊĉĉĉĉ ĉ span List . add First ( čĊĉĉĉĉĉ ĉ start , Ġsb . length , čĊĉĉĉĉĉ ĉ My Clickable Span ( čĊĉĉĉĉĉĉ ĉ sb . substring ( start , Ġsb . length ) čĊĉĉĉĉĉĉ ĉ , Ġurl čĊĉĉĉĉĉĉ ĉ , Ġlink Helper . find Ac ct Color ( url ) čĊĉĉĉĉĉĉ ĉ , Ġoptions . link Tag čĊĉĉĉĉĉ ĉ ) čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ }), čĊĉĉčĊĉ ĉ TITLE ({ čĊĉĉ ĉ close Previous Block () čĊĉĉĉčĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) Ġ// Ġ æĶ¹ è¡Į ãĤĴ åĲ« ãģ¾ ãģªãģĦ ãģĵãģ¨ ãģĮ åĪĨ ãģĭ ãģ£ ãģ¦ãģĦãĤĭ čĊĉĉ ĉ span List . add Last ( čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ sb . length , čĊĉĉĉ ĉ android . text . style . Alignment Span . Standard ( android . text . Layout . Alignment . ALIGN _ CENTER ) čĊĉĉ ĉ ) čĊĉĉ ĉ span List . add Last ( čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ sb . length , čĊĉĉĉ ĉ android . text . style . BackgroundColor Span ( 0 x 2 0 8 0 8 0 8 0 ) čĊĉĉ ĉ ) čĊĉĉ ĉ span List . add Last ( start , Ġsb . length , Ġandroid . text . style . Relative Size Span ( 1 . 5 f )) čĊĉĉĉčĊĉĉ ĉ close Block () čĊĉ ĉ }), čĊĉĉčĊĉ ĉ CENTER ({ čĊĉĉ ĉ close Previous Block () čĊĉĉĉčĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉ ĉ if ( it . quote Nest Ġ> Ġ 0 ) Ġ{ čĊĉĉĉ ĉ // Ġ å¼ķçĶ¨ ãĥį ãĤ¹ãĥĪ ãģ® åĨħéĥ¨ ãģ§ãģ¯ ãĤ» ãĥ³ ãĤ¿ ãĥª ãĥ³ãĤ° ãģķ ãģĽ ãĤĭ ãģ¨ å¼ķçĶ¨ ãĥŀ ãĥ¼ãĤ « ãĥ¼ ãģ¾ãģ§ åĭķ ãģĦãģ¦ ãģĹãģ¾ ãģĨ ãģ®ãģ§ čĊĉĉĉ ĉ // ĠãĤ » ãĥ³ ãĤ¿ ãĥª ãĥ³ãĤ° ãģĮ æ©Łèĥ½ ãģĹãģªãģĦ ãĤĪãģĨãģ« ãģĻãĤĭ čĊĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉ ĉ span List . add Last ( čĊĉĉĉĉ ĉ start , čĊĉĉĉĉ ĉ sb . length , čĊĉĉĉĉ ĉ android . text . style . Alignment Span . Standard ( čĊĉĉĉĉĉ ĉ android . text . Layout . Alignment . ALIGN _ CENTER čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ ) čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ close Block () čĊĉ ĉ }), čĊĉĉčĊĉ ĉ QUOTE _ BLOCK ({ čĊĉĉ ĉ close Previous Block () čĊĉĉĉčĊĉĉ ĉ val Ġstart Ġ= Ġthis . start čĊĉĉĉčĊĉĉ ĉ // Ġ æľ« å°¾ ãģ« ãģĤãĤĭ ç©º çĻ½ ãģ® ãĥĨ ãĤŃ ãĤ¹ãĥĪ ãĥİ ãĥ¼ãĥī ãĤĴ éĻ¤ åİ» ãģĻãĤĭ čĊĉĉ ĉ while ( it . childNodes . isNotEmpty ()) Ġ{ čĊĉĉĉ ĉ val Ġlast Ġ= Ġit . childNodes . last () čĊĉĉĉ ĉ if ( last . type Ġ== ĠNode Type . TEXT Ġ&& Ġlast . args [ 0 ]. isBlank ()) Ġ{ čĊĉĉĉĉ ĉ it . childNodes . remove Last () čĊĉĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉĉ ĉ break čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉĉĉčĊĉĉ ĉ val Ġbg _ color Ġ= Ġquote Nest Colors [ it . quote Nest Ġ% Ġquote Nest Colors . size ] čĊĉĉ ĉ // ĠTextView Ġãģ® æĸĩåŃĹ è£ħ é£ ¾ ãģ§ãģ¯ ãĢĮ ãĥĸ ãĥŃ ãĥĥãĤ¯ è¦ģ ç´ł ãģ® åħ¥ ãĤĮ åŃĲ ãĢį ãĤĴ è¡¨ çı¾ ãģ§ãģį ãģªãģĦ čĊĉĉ ĉ // Ġ åĨħå®¹ ãģ® åĲĦ è¡Į ãģ® å§ĭ ç«¯ ãģ« ä½ķ ãģĭ è¿½åĬł ãģĻãĤĭãģ¨ ãģĦãģĨ ãģ® ãģĮ ãģ¾ ãģļ ãĤŃ ãĥĦ ãģĦ čĊĉĉ ĉ // Ġ ãģĹãģ ĭ ãģĹ åĲĦ è¡Į ãģ® éł Ń ãģ« å¼ķçĶ¨ ãĥŀ ãĥ¼ãĤ¯ ãĤĴ ãģ¤ ãģĳ ãģªãģĦ ãģ¨ å¼ķçĶ¨ ãģ® ãĥį ãĤ¹ãĥĪ ãģ§ æĦı åĳ³ ãģĮ éĢļ ãģĺ ãģªãģı ãģª ãģ£ãģ¦ ãģĹãģ¾ ãģĨ čĊĉĉ ĉ val Ġtmp Ġ= Ġsb . toString () čĊĉĉ ĉ // log . d (" QUOTE _ BLOCK Ġtmp =${ tmp } Ġstart =$ start Ġend =${ tmp . length }") čĊĉĉ ĉ for ( i Ġin Ġtmp . length Ġ- Ġ 1 Ġdown To Ġstart ) Ġ{ čĊĉĉĉ ĉ val Ġprev Char Ġ= Ġwhen ( i ) Ġ{ čĊĉĉĉĉ ĉ start Ġ-> Ġ'\ n ' čĊĉĉĉĉ ĉ else Ġ-> Ġtmp [ i Ġ- Ġ 1 ] čĊĉĉĉ ĉ } čĊĉĉĉ ĉ // log . d (" QUOTE _ BLOCK Ġprev Char =${ ĠString . format ("% x ", prev Char . toInt ()) }") čĊĉĉĉ ĉ if ( prev Char Ġ== Ġ'\ n ') Ġ{ čĊĉĉĉĉ ĉ // log . d (" QUOTE _ BLOCK Ġinsert ! Ġi =$ i ") čĊĉĉĉĉ ĉ sb . insert ( i , Ġ"> Ġ") čĊĉĉĉĉ ĉ span List . insert ( i , Ġ 2 ) čĊĉĉĉĉ ĉ span List . add Last ( čĊĉĉĉĉĉ ĉ i , Ġi Ġ+ Ġ 1 , čĊĉĉĉĉĉ ĉ android . text . style . BackgroundColor Span ( bg _ color ) čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ span List . add Last ( čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ sb . length , čĊĉĉĉ ĉ font Span ( Type face . default From Style ( android . graphics . Type face . ITAL IC )) čĊĉĉ ĉ ) čĊĉĉĉčĊĉĉ ĉ close Block () čĊĉ ĉ }), čĊĉĉčĊĉ ĉ ROOT ({ čĊĉĉ ĉ fire Render Child Nodes ( it ) čĊĉ ĉ }), čĊĉĉčĊĉ ĉ ; čĊĉĉčĊĉ ĉ comp anion Ġobject Ġ{ čĊĉĉĉčĊĉĉ ĉ // Ġ ãģĤãĤĭ ãĥİ ãĥ¼ãĥī ãģĮ åĨħéĥ¨ ãģ« æĮģ ãģ¦ ãĤĭ ãĥİ ãĥ¼ãĥī ç¨® åĪ¥ ãģ® ãĥŀ ãĥĥãĥĹ čĊĉĉ ĉ val Ġmap Allow Inside Ġ= ĠHashMap < NodeType , ĠHashSet < NodeType >> (). apply Ġ{ čĊĉĉĉĉčĊĉĉĉ ĉ fun Ġ< T > Ġhash Set Of ( var arg Ġvalues Ġ: ĠT ) Ġ= ĠHashSet < T >(). apply Ġ{ Ġadd All ( values ) Ġ} čĊĉĉĉĉčĊĉĉĉ ĉ infix Ġfun ĠNode Type . wrap s ( inner Ġ: ĠHashSet < NodeType >) Ġ= Ġput ( this , Ġinner ) čĊĉĉĉĉčĊĉĉĉ ĉ // ĠE MO JI , ĠHAS HT AG , ĠM ENT ION , ĠCODE _ BLOCK , ĠQU OTE _ INLINE , ĠSEARCH Ġ çŃī ãģ¯ ãĥŀ ãĥ¼ãĤ¯ ãĥĢ ãĤ¦ ãĥ³ è¦ģ ç´ł ãģ® ãĥį ãĤ¹ãĥĪ ãĤĴ è¨± åı¯ ãģĹãģªãģĦ čĊĉĉĉĉčĊĉĉĉ ĉ BIG Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , čĊĉĉĉĉĉ ĉ STRI KE , ĠSMALL , ĠIT AL IC čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ BOLD Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ STRI KE , ĠSMALL , ĠIT AL IC čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ STRI KE Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ BIG , ĠB OLD , ĠSMALL , ĠIT AL IC čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ SMALL Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ BOLD , ĠSTR I KE , ĠIT AL IC čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ ITAL IC Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ BIG , ĠB OLD , ĠSTR I KE , ĠSMALL čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ MOT ION Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ BOLD , ĠSTR I KE , ĠSMALL , ĠIT AL IC čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ LINK Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠM OT ION , čĊĉĉĉĉĉ ĉ BIG , ĠB OLD , ĠSTR I KE , ĠSMALL , ĠIT AL IC čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ TITLE Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ BIG , ĠB OLD , ĠSTR I KE , ĠSMALL , ĠIT AL IC , čĊĉĉĉĉĉ ĉ MOT ION , ĠCODE _ INLINE čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ CENTER Ġwraps čĊĉĉĉĉ ĉ hash Set Of ( čĊĉĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉĉ ĉ BIG , ĠB OLD , ĠSTR I KE , ĠSMALL , ĠIT AL IC , čĊĉĉĉĉĉ ĉ MOT ION , ĠCODE _ INLINE čĊĉĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ // Ġall Ġexcept ĠROOT , TEXT čĊĉĉĉ ĉ val Ġall Set Ġ= Ġhash Set Of ( čĊĉĉĉĉ ĉ CODE _ BLOCK , ĠQU OTE _ INLINE , ĠSEARCH , čĊĉĉĉĉ ĉ E MO JI , ĠHAS HT AG , ĠM ENT ION , ĠURL , ĠLINK , čĊĉĉĉĉ ĉ BIG , ĠB OLD , ĠSTR I KE , ĠSMALL , ĠIT AL IC , čĊĉĉĉĉ ĉ MOT ION , ĠCODE _ INLINE , čĊĉĉĉĉ ĉ TITLE , ĠC ENTER , ĠQU OTE _ BLOCK čĊĉĉĉ ĉ ) čĊĉĉĉĉčĊĉĉĉ ĉ QUOTE _ BLOCK Ġwraps Ġall Set čĊĉĉĉĉčĊĉĉĉ ĉ ROOT Ġwraps Ġall Set čĊĉĉĉĉ čĊĉĉ ĉ } čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ // Ġãĥ ŀ ãĥ¼ãĤ¯ ãĥĢ ãĤ¦ ãĥ³ è¦ģ ç´ł čĊ ĉ internal Ġclass ĠNode ( čĊĉ ĉ val Ġtype Ġ: ĠNode Type , Ġ// Ġãĥ İ ãĥ¼ãĥī ç¨® åĪ¥ čĊĉ ĉ val Ġargs Ġ: ĠArray < String > Ġ= Ġempty Array (), Ġ// Ġ å¼ķ æķ° čĊĉ ĉ parentNode Ġ: ĠNode ? čĊ ĉ ) Ġ{ čĊĉĉčĊĉ ĉ val Ġchild Nodes Ġ= ĠLinkedList < Node >() čĊĉĉčĊĉ ĉ internal Ġval Ġquote Nest Ġ: ĠInt Ġ= Ġ( parentNode ?. quote Nest Ġ?: Ġ 0 ) Ġ+ Ġwhen ( type ) Ġ{ čĊĉĉ ĉ NodeType . QUOTE _ BLOCK , ĠNode Type . QUOTE _ INLINE Ġ-> Ġ 1 čĊĉĉ ĉ else Ġ-> Ġ 0 čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ // Ġãĥ ŀ ãĥ¼ãĤ¯ ãĥĢ ãĤ¦ ãĥ³ è¦ģ ç´ł ãģ® åĩº çı¾ ä½įç½® čĊ ĉ internal Ġclass ĠNode Detected ( čĊĉ ĉ val Ġnode Ġ: ĠNode , čĊĉ ĉ val Ġstart Ġ: ĠInt , Ġ// Ġãĥ Ĩ ãĤŃ ãĤ¹ãĥĪ ä¸Ń ãģ® éĸĭå§ĭ ä½įç½® čĊĉ ĉ val Ġend Ġ: ĠInt , Ġ// Ġãĥ Ĩ ãĤŃ ãĤ¹ãĥĪ ä¸Ń ãģ® çµĤ äºĨ ä½įç½® čĊĉ ĉ val Ġtext Inside Ġ: ĠString , Ġ// Ġ åĨħéĥ¨ ç¯Ħ åĽ ² ãĢĤ è¦ ª ãģĭãĤī ç¶ Ļ æī¿ ãģĻãĤĭ åł´åĲĪ ãĤĤ ãģĤãĤĭ ãģĹ çĭ¬ èĩª ãģ« ä½ľ ãĤĭ åł´åĲĪ ãĤĤ ãģĤãĤĭ čĊĉ ĉ val Ġstart Inside Ġ: ĠInt , Ġ// Ġ åĨħéĥ¨ ç¯Ħ åĽ ² ãģ® éĸĭå§ĭ ä½įç½® čĊĉ ĉ private Ġval Ġlength Inside Ġ: ĠInt Ġ// Ġ åĨħéĥ¨ ç¯Ħ åĽ ² ãģ® çµĤ äºĨ ä½įç½® čĊ ĉ ) Ġ{ čĊĉĉčĊĉ ĉ val Ġend Inside Ġ: ĠInt čĊĉĉ ĉ get () Ġ= Ġstart Inside Ġ+ Ġlength Inside čĊ ĉ } čĊĉčĊ ĉ internal Ġclass ĠNode Parse Env ( čĊĉ ĉ private Ġval Ġparent Node Ġ: ĠNode , čĊĉ ĉ val Ġtext Ġ: ĠString , čĊĉ ĉ start Ġ: ĠInt , čĊĉ ĉ val Ġend Ġ: ĠInt čĊ ĉ ) Ġ{ čĊĉĉčĊĉ ĉ private Ġval Ġchild Nodes Ġ= Ġparent Node . childNodes čĊĉ ĉ private Ġval Ġallow Inside Ġ: ĠHashSet < NodeType > Ġ= čĊĉĉ ĉ NodeType . map Allow Inside [ parentNode . type ] Ġ?: Ġhash Set Of () čĊĉĉčĊĉ ĉ // Ġ çĽ´ åīį ãģ® ãĥİ ãĥ¼ãĥī ãģ® çµĤ äºĨ ä½įç½® čĊĉ ĉ internal Ġvar Ġlast End Ġ= Ġstart čĊĉĉčĊĉ ĉ // Ġ æ³¨ çĽ® ä¸Ń ãģ® ä½įç½® čĊĉ ĉ internal Ġvar Ġpos Ġ: ĠInt Ġ= Ġ 0 čĊĉĉčĊĉ ĉ // Ġ çĽ´ åīį ãģ® ãĥİ ãĥ¼ãĥī ãģ® çµĤ äºĨ ä½įç½® ãģĭãĤī æ¬¡ãģ® ãĥİ ãĥ¼ãĥī ãģ® éĸĭå§ĭ ä½įç½® ãģ® æīĭ åīį ãģ¾ãģ§ ãĤĴ result ãģ« è¿½åĬł ãģĻãĤĭ čĊĉ ĉ private Ġfun Ġclose Text ( end Text Ġ: ĠInt ) Ġ{ čĊĉĉ ĉ val Ġlength Ġ= Ġend Text Ġ- Ġlast End čĊĉĉ ĉ if ( length Ġ<= Ġ 0 ) Ġreturn čĊĉĉ ĉ val Ġtext Inside Ġ= Ġtext . substring ( last End , Ġend Text ) čĊĉĉ ĉ childNodes . add ( Node ( NodeType . TEXT , ĠarrayOf ( text Inside ), Ġnull )) čĊĉ ĉ } čĊĉĉčĊĉ ĉ fun Ġremain Matcher ( pattern Ġ: ĠPattern ) Ġ= čĊĉĉ ĉ Matcher Cache . matcher ( pattern , Ġtext , Ġpos , Ġend ) čĊĉĉčĊĉ ĉ fun Ġparse Inside () Ġ{ čĊĉĉ ĉ if ( allow Inside . isEmpty ()) Ġreturn čĊĉĉĉčĊĉĉ ĉ var Ġi Ġ= Ġlast End Ġ// ãĤ¹ ãĤŃ ãĥ£ ãĥ³ ä¸Ń ãģ® ä½įç½® čĊĉĉ ĉ while ( i Ġ< Ġend ) Ġ{ čĊĉĉĉ ĉ // Ġ æ³¨ çĽ® ä½įç½® ãģ® æĸĩåŃĹ ãģ«éĸ¢ éĢ£ ãģĻãĤĭ ãĥĳ ãĥ¼ãĤ µ ãĥ¼ čĊĉĉĉ ĉ val Ġlast Parsers Ġ= Ġnode Parser Map [ text [ i ]. toInt ()] čĊĉĉĉ ĉ if ( last Parsers Ġ== Ġnull ) Ġ{ čĊĉĉĉĉ ĉ ++ Ġi čĊĉĉĉĉ ĉ continue čĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ // Ġãĥĳ ãĥ¼ãĤ µ ãĥ¼ çĶ¨ ãģ® ãĥĳ ãĥ©ãĥ¡ãĥ¼ãĤ¿ ãĤĴ çĶ¨ æĦı ãģĻãĤĭ čĊĉĉĉ ĉ // Ġ éĥ¨åĪĨ æĸĩåŃĹåĪĹ ãģ® ãĤ³ ãĤ¹ãĥĪ ãģ¯ é«ĺ ãģı ãģªãģĦ ãģ¨ ä¿¡ ãģĺ ãģŁ ãģĦ čĊĉĉĉ ĉ pos Ġ= Ġi čĊĉĉĉĉčĊĉĉĉ ĉ val Ġdetected Ġ= Ġlast Parsers . first NonNull Ġ{ čĊĉĉĉĉ ĉ val Ġd Ġ= Ġthis . it () čĊĉĉĉĉ ĉ if ( d Ġ== Ġnull ) Ġ{ čĊĉĉĉĉĉ ĉ null čĊĉĉĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉĉĉ ĉ val Ġn Ġ= Ġd . node čĊĉĉĉĉĉ ĉ if (! Ġallow Inside . contains ( d . node . type )) Ġ{ čĊĉĉĉĉĉĉ ĉ log . w ( čĊĉĉĉĉĉĉĉ ĉ " not Ġallowed Ġ: Ġ${ parentNode . type } Ġ=> Ġ${ n . type } Ġ${ text . substring ( čĊĉĉĉĉĉĉĉĉ ĉ d . start , čĊĉĉĉĉĉĉĉĉ ĉ d . end čĊĉĉĉĉĉĉĉ ĉ )}" čĊĉĉĉĉĉĉ ĉ ) čĊĉĉĉĉĉĉ ĉ null čĊĉĉĉĉĉ ĉ } Ġelse Ġ{ čĊĉĉĉĉĉĉ ĉ d čĊĉĉĉĉĉ ĉ } čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ if ( detected Ġ== Ġnull ) Ġ{ čĊĉĉĉĉ ĉ ++ Ġi čĊĉĉĉĉ ĉ continue čĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ close Text ( detected . start ) čĊĉĉĉ ĉ childNodes . add ( detected . node ) čĊĉĉĉ ĉ i Ġ= Ġdetected . end čĊĉĉĉ ĉ last End Ġ= Ġi čĊĉĉĉĉčĊĉĉĉ ĉ Node Parse Env ( čĊĉĉĉĉ ĉ detected . node , čĊĉĉĉĉ ĉ detected . text Inside , čĊĉĉĉĉ ĉ detected . start Inside , čĊĉĉĉĉ ĉ detected . end Inside čĊĉĉĉ ĉ ). parse Inside () čĊĉĉ ĉ } čĊĉĉ ĉ close Text ( end ) čĊĉ ĉ } čĊĉĉčĊĉ ĉ internal Ġfun Ġmake Detected ( čĊĉĉ ĉ type Ġ: ĠNode Type , čĊĉĉ ĉ args Ġ: ĠArray < String >, čĊĉĉ ĉ start Ġ: ĠInt , čĊĉĉ ĉ end Ġ: ĠInt , čĊĉĉ ĉ text Inside Ġ: ĠString , čĊĉĉ ĉ start Inside Ġ: ĠInt , čĊĉĉ ĉ length Inside Ġ: ĠInt čĊĉ ĉ ) Ġ: ĠNode Detected Ġ{ čĊĉĉĉčĊĉĉ ĉ val Ġnode Ġ= ĠNode ( type , Ġargs , Ġparent Node ) čĊĉĉĉčĊĉĉ ĉ if ( DEBUG ) Ġlog . d ( čĊĉĉĉ ĉ " Node Detected : Ġ${ node . type } Ġinside =${ čĊĉĉĉ ĉ text Inside . substring ( start Inside , Ġstart Inside Ġ+ Ġlength Inside ) čĊĉĉĉ ĉ }" čĊĉĉ ĉ ) čĊĉĉĉčĊĉĉ ĉ return ĠNode Detected ( čĊĉĉĉ ĉ node , čĊĉĉĉ ĉ start , čĊĉĉĉ ĉ end , čĊĉĉĉ ĉ text Inside , čĊĉĉĉ ĉ start Inside , čĊĉĉĉ ĉ length Inside čĊĉĉ ĉ ) čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ // Ġãĥ İ ãĥ¼ãĥī ãģ® ãĥĳ ãĥ¼ãĤ¹ ãĤĴè¡Į ãģĨ éĸ¢æķ° ãĤĴ ãĤŃ ãĥ£ ãĥĹ ãĥģ ãĥ£ ãĥĳ ãĥ©ãĥ¡ãĥ¼ãĤ¿ ãģ¤ ãģį ãģ§ çĶŁæĪĲ ãģĻãĤĭ čĊ ĉ private Ġfun Ġsimple Parser ( čĊĉ ĉ pattern Ġ: ĠPattern čĊĉ ĉ , Ġtype Ġ: ĠNode Type čĊ ĉ ) Ġ: ĠNode Parse Env . () Ġ-> ĠNode Detected ? Ġ= Ġ{ čĊĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( pattern ) čĊĉ ĉ when Ġ{ čĊĉĉ ĉ ! Ġmatcher . find () Ġ-> Ġnull čĊĉĉĉčĊĉĉ ĉ else Ġ-> Ġ{ čĊĉĉĉĉčĊĉĉĉ ĉ val Ġtext Inside Ġ= Ġmatcher . group ( 1 ) čĊĉĉĉ ĉ make Detected ( čĊĉĉĉĉ ĉ type , čĊĉĉĉĉ ĉ array Of ( text Inside ), čĊĉĉĉĉ ĉ matcher . start (), Ġmatcher . end (), čĊĉĉĉĉ ĉ this . text , Ġmatcher . start ( 1 ), Ġtext Inside . length čĊĉĉĉ ĉ ) čĊĉĉĉĉ čĊĉĉ ĉ } čĊĉ ĉ } čĊ ĉ } čĊĉčĊ ĉ // Ġ( ãĥŀ ãĥ¼ãĤ¯ ãĥĢ ãĤ¦ ãĥ³ è¦ģ ç´ł ãģ® çī¹ å¾ ´ çļĦãģª æĸĩåŃĹ ) ãģ¨ ( ãĥĳ ãĥ¼ãĤ µ éĸ¢æķ° ãģ® éħį åĪĹ ) ãģ® ãĥŀ ãĥĥãĥĹ čĊ ĉ private Ġval Ġnode Parser Map Ġ= ĠSparse Array < Array < out ĠNode Parse Env . () Ġ-> ĠNode Detected ? >> (). apply Ġ{ čĊĉĉčĊĉ ĉ fun Ġadd Parser ( čĊĉĉ ĉ first Chars Ġ: ĠString , čĊĉĉ ĉ var arg Ġnode Parsers Ġ: ĠNode Parse Env . () Ġ-> ĠNode Detected ? čĊĉ ĉ ) Ġ{ čĊĉĉ ĉ for ( s Ġin Ġfirst Chars ) Ġ{ čĊĉĉĉ ĉ put ( s . toInt (), Ġnode Parsers ) čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ // ĠStri ke Ġ~~ ... ~~ čĊĉ ĉ add Parser ( čĊĉĉ ĉ " ~ " čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" \ A ~~ (. + ?) ~~ """) čĊĉĉĉ ĉ , ĠNode Type . STRI KE čĊĉĉ ĉ ) čĊĉ ĉ ) čĊĉĉčĊĉ ĉ // ĠQuote Ġ" ..." čĊĉ ĉ add Parser ( čĊĉĉ ĉ "\ "" čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" \ A " ([ ^\ x 0 d \ x 0 a ]+ ? )\ n " [\ x 0 d \ x 0 a ]* """) čĊĉĉĉ ĉ , ĠNode Type . QUOTE _ INLINE čĊĉĉ ĉ ) čĊĉ ĉ ) čĊĉĉčĊĉ ĉ // ĠQuote Ġ( è¡Į éł Ń )> ... ( æĶ¹ è¡Į ) čĊĉ ĉ val Ġre Quote Block Ġ= ĠPattern . compile ( čĊĉĉ ĉ // Ġãģĵãģ® æŃ£ è¦ı è¡¨ çı¾ ãģ® åł´åĲĪãģ¯ Ġ\ A Ġ ãģ§ãģ¯ ãģªãģı Ġ^ Ġãģ§ åĲĦ è¡Į ãģ® å§ĭ ç«¯ ãģ« ãĥŀ ãĥĥ ãĥģ ãģķ ãģĽ ãĤĭ čĊĉĉ ĉ """ ^ >( ?: [ Ġ ãĢĢ ] ?) ([ ^\ x 0 d \ x 0 a ]* )( \ x 0 a |\ x 0 d \ x 0 a ? )? """, čĊĉĉ ĉ Pattern . MULT IL INE čĊĉ ĉ ) čĊĉĉčĊĉ ĉ add Parser ("> ", Ġ{ čĊĉĉ ĉ if ( pos Ġ> Ġ 0 ) Ġ{ čĊĉĉĉ ĉ val Ġc Ġ= Ġtext [ pos Ġ- Ġ 1 ] čĊĉĉĉ ĉ if ( c Ġ!= Ġ'\ r ' Ġ&& Ġc Ġ!= Ġ'\ n ') Ġ{ čĊĉĉĉĉ ĉ // çĽ´ åīį ãģĮ æĶ¹ è¡Į æĸĩåŃĹ ãģ§ãģ¯ ãģªãģĦ čĊĉĉĉĉ ĉ if ( DEBUG ) Ġlog . d (" QUOTE : Ġprevious Ġchar Ġis Ġnot Ġline Ġend . Ġ${ c } Ġpos =$ pos Ġtext =$ text ") čĊĉĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ var Ġp Ġ= Ġpos čĊĉĉ ĉ val Ġcontent Ġ= ĠStringBuilder () čĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( re Quote Block ) čĊĉĉ ĉ while ( true ) Ġ{ čĊĉĉĉ ĉ if (! Ġmatcher . find ( p )) Ġbreak čĊĉĉĉ ĉ p Ġ= Ġmatcher . end () čĊĉĉĉ ĉ if ( content . isNotEmpty ()) Ġcontent . append ('\ n ') čĊĉĉĉ ĉ content . append ( matcher . group ( 1 )) čĊĉĉĉ ĉ // Ġ æĶ¹ è¡Į ãģ® çĽ´ å¾Į ãģª ãģ®ãģ§ æ¬¡ åĽŀ ãĥŀ ãĥĥ ãĥģ ãģ® Ġ^ Ġãģ¯ å¤§ ä¸ Ī å¤« ãģª ãģ¯ ãģļ âĢ¦ čĊĉĉ ĉ } čĊĉĉ ĉ if ( content . isNotEmpty ()) Ġcontent . append ('\ n ') čĊĉĉĉčĊĉĉ ĉ if ( p Ġ<= Ġpos ) Ġ{ čĊĉĉĉ ĉ // Ġ> Ġãģ® ãģĤ ãģ¨ ãģ« åħ¨ ãģı ä½ķ ãĤĤ ãģªãģĦ čĊĉĉĉ ĉ if ( DEBUG ) Ġlog . d (" QUOTE : Ġnot Ġa Ġquote ") čĊĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉ ĉ } čĊĉĉ ĉ val Ġtext Inside Ġ= Ġcontent . toString () čĊĉĉĉčĊĉĉ ĉ make Detected ( čĊĉĉĉ ĉ NodeType . QUOTE _ BLOCK , čĊĉĉĉ ĉ empty Array (), čĊĉĉĉ ĉ pos , Ġp , čĊĉĉĉ ĉ text Inside , Ġ 0 , Ġtext Inside . length čĊĉĉ ĉ ) čĊĉ ĉ }) čĊĉĉčĊĉ ĉ // Ġ çµ µ æĸĩåŃĹ Ġ: emoji : čĊĉ ĉ add Parser ( čĊĉĉ ĉ ":" čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" \ A : ([ a - zA - Z 0 - 9 +- _ ]+ ): """) čĊĉĉĉ ĉ , ĠNode Type . E MO JI čĊĉĉ ĉ ) čĊĉ ĉ ) čĊĉĉčĊĉ ĉ add Parser ( čĊĉĉ ĉ " (" čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" \ A \ Q (( (\ E (. + ? )\ Q ))) \ E """, ĠPattern . DOT ALL ) čĊĉĉĉ ĉ , ĠNode Type . MOT ION čĊĉĉ ĉ ) čĊĉ ĉ ) čĊĉĉčĊĉ ĉ val Ġre Html Tag Ġ= ĠPattern . compile (""" \ A < ([ a - z ]+) >( .+ ? )</ \ 1 > """, ĠPattern . DOT ALL ) čĊĉĉčĊĉ ĉ add Parser ("< ", Ġ{ čĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( re Html Tag ) čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatcher . find () Ġ-> Ġnull čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġ{ čĊĉĉĉĉ ĉ val ĠtagName Ġ= Ġmatcher . group ( 1 ) čĊĉĉĉĉ ĉ val Ġtext Inside Ġ= Ġmatcher . group ( 2 ) čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ fun Ġa ( type Ġ: ĠNode Type ) Ġ= Ġmake Detected ( čĊĉĉĉĉĉ ĉ type , čĊĉĉĉĉĉ ĉ array Of ( text Inside ), čĊĉĉĉĉĉ ĉ matcher . start (), Ġmatcher . end (), čĊĉĉĉĉĉ ĉ this . text , Ġmatcher . start ( 2 ), Ġtext Inside . length čĊĉĉĉĉ ĉ ) čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ when ( tagName ) Ġ{ čĊĉĉĉĉĉ ĉ " motion " Ġ-> Ġa ( NodeType . MOT ION ) čĊĉĉĉĉĉ ĉ " center " Ġ-> Ġa ( NodeType . CENTER ) čĊĉĉĉĉĉ ĉ " small " Ġ-> Ġa ( NodeType . SMALL ) čĊĉĉĉĉĉ ĉ " i " Ġ-> Ġa ( NodeType . ITAL IC ) čĊĉĉĉĉĉ ĉ else Ġ-> Ġnull čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ }) čĊĉĉčĊĉ ĉ // Ġ*** big *** Ġ** bold ** čĊĉ ĉ add Parser ( čĊĉĉ ĉ " *" čĊĉĉ ĉ // Ġ åĩ¦çĲĨ éłĨ åºı ãģ« æĦı åĳ³ ãģĮãģĤãĤĭ ãģ®ãģ§ åħ¥ ãĤĮ æĽ¿ ãģĪ ãģªãģĦ ãģĵãģ¨ čĊĉĉ ĉ // Ġ è¨ĺ åı· åĪĹ ãģĮ éķ· ãģĦ éłĨ ãģ« ãĥĳ ãĥ¼ãĤ¹ ãĤĴ è© ¦ ãģĻ čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" ^\ Q *** \ E (. + ? )\ Q *** \ E """) čĊĉĉĉ ĉ , ĠNode Type . BIG čĊĉĉ ĉ ) čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" ^\ Q ** \ E (. + ? )\ Q ** \ E """) čĊĉĉĉ ĉ , ĠNode Type . BOLD čĊĉĉ ĉ ) čĊĉ ĉ ) čĊĉĉčĊĉ ĉ val Ġre Al num Ġ= ĠPattern . compile (""" [ A - Z 0 - 9 ] """, ĠPattern . CASE _ INS ENS ITIVE ) čĊĉĉčĊĉ ĉ // Ġhttp ( s ) :// .... čĊĉ ĉ val Ġre Url Ġ= ĠPattern . compile (""" \ A ( https ? :// [\ w / :% # @ ${ '$ '} & ?! ()\ [\ ] ~ .= + \- ]+) """) čĊĉ ĉ add Parser (" h ", Ġ{ čĊĉĉĉčĊĉĉ ĉ // Ġ çĽ´ åīį ãģ® æĸĩåŃĹ ãģĮ èĭ± æķ°åŃĹ ãģª ãĤī URL ãģ® éĸĭå§ĭ ãģ¨ ãģ¯ ãģ¿ ãģª ãģķ ãģªãģĦ čĊĉĉ ĉ if ( pos Ġ> Ġ 0 Ġ&& ĠMatcher Cache . matcher ( re Al num , Ġtext , Ġpos Ġ- Ġ 1 , Ġpos ). find ()) Ġ{ čĊĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( re Url ) čĊĉĉ ĉ if (! Ġmatcher . find ()) Ġ{ čĊĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ val Ġurl Ġ= Ġmatcher . group ( 1 ). remove Or phan ed Br ackets ( url Safe Ġ= Ġtrue ) čĊĉĉ ĉ make Detected ( čĊĉĉĉ ĉ NodeType . URL , čĊĉĉĉ ĉ array Of ( url ), čĊĉĉĉ ĉ matcher . start (), Ġmatcher . start () Ġ+ Ġurl . length , čĊĉĉĉ ĉ "", Ġ 0 , Ġ 0 čĊĉĉ ĉ ) čĊĉ ĉ }) čĊĉĉčĊĉ ĉ // Ġæ ¤ ľç´¢ čĊĉ ĉ val Ġre Search Button Ġ= ĠPattern . compile ( čĊĉĉ ĉ """ \ A ( æ¤ ľç´¢ |\ [ æ¤ ľç´¢ ]| Search |\ [ Search ]) (\ n |\ z ) """ čĊĉĉ ĉ , ĠPattern . CASE _ INS ENS ITIVE čĊĉ ĉ ) čĊĉĉčĊĉ ĉ fun ĠNode Parse Env . parse Search Prev () Ġ: ĠString ? Ġ{ čĊĉĉ ĉ val Ġprev Ġ= Ġtext . substring ( last End , Ġpos ) čĊĉĉ ĉ val Ġdel m Ġ= Ġprev . lastIndexOf ('\ n ') čĊĉĉ ĉ val Ġend Ġ= Ġprev . length čĊĉĉ ĉ return Ġwhen Ġ{ čĊĉĉĉ ĉ end Ġ<= Ġ 1 Ġ-> Ġnull Ġ// ĠãĤ Ń ãĥ¼ãĥ ¯ ãĥ¼ãĥī ãĤĴ åĲ« ãģ¾ ãģªãģĦ ãģı ãĤī ãģĦ çŁŃ ãģĦ čĊĉĉĉ ĉ del m Ġ+ Ġ 1 Ġ>= Ġend Ġ- Ġ 1 Ġ-> Ġnull Ġ// Ġ æĶ¹ è¡Į ãĤĪ ãĤĬ å¾Į ãģ® éĥ¨åĪĨ ãģĮ çŁŃ ãģĻ ãģ İ ãĤĭ čĊĉĉĉ ĉ ! Ġ" Ġ ãĢĢ ". contains ( prev . last ()) Ġ-> Ġnull Ġ// Ġ æľ« å°¾ ãģĮ ç©º çĻ½ ãģ§ãģ¯ ãģªãģĦ čĊĉĉĉ ĉ else Ġ-> Ġprev . substring ( del m Ġ+ Ġ 1 , Ġend Ġ- Ġ 1 ) Ġ// ĠãĤ Ń ãĥ¼ãĥ ¯ ãĥ¼ãĥī éĥ¨åĪĨ ãĤĴ è¿Ķ ãģĻ čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ val Ġsearch Parser Ġ: ĠNode Parse Env . () Ġ-> ĠNode Detected ? Ġ= Ġ{ čĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( re Search Button ) čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatcher . find () Ġ-> Ġnull čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġ{ čĊĉĉĉĉ ĉ val Ġkeyword Ġ= Ġparse Search Prev () čĊĉĉĉĉ ĉ when Ġ{ čĊĉĉĉĉĉ ĉ keyword ?. isEmpty () Ġ!= Ġfalse Ġ-> Ġnull čĊĉĉĉĉĉĉ čĊĉĉĉĉĉ ĉ else Ġ-> Ġmake Detected ( čĊĉĉĉĉĉĉ ĉ NodeType . SEARCH , čĊĉĉĉĉĉĉ ĉ array Of ( keyword ), čĊĉĉĉĉĉĉ ĉ pos Ġ- Ġ( keyword . length Ġ+ Ġ 1 ), Ġmatcher . end (), čĊĉĉĉĉĉĉ ĉ this . text , Ġpos Ġ- Ġ( keyword . length Ġ+ Ġ 1 ), Ġkeyword . length čĊĉĉĉĉĉ ĉ ) čĊĉĉĉĉ ĉ } čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ // Ġ[ title ] ĠãĢĲ title ãĢĳ čĊĉ ĉ // Ġ çĽ´ å¾Į ãģ« æĶ¹ è¡Į ãģĮ å¿ħè¦ģ ãģł ãģ£ãģŁ ãģĮ æĸĩ æľ« ãģ§ ãĤĤ èī¯ ãģĦ ãģĵãģ¨ ãģ«ãģª ãģ£ãģŁ Ġhttps :// github . com / sy ui lo / miss key / commit / 7 9 ff bf 9 5 db 9 d 0 cc 0 1 9 d 0 6 ab 9 3 b 1 bfa 6 ba 0 d 4 f 9 ae čĊĉ ĉ val Ġtitle Parser Ġ= Ġsimple Parser ( čĊĉĉ ĉ Pattern . compile (""" \ A [ ãĢĲ \[ ]( .+ ? )[ ãĢĳ \] ]( \ n |\ z ) """) čĊĉĉ ĉ , ĠNode Type . TITLE čĊĉ ĉ ) čĊĉĉčĊĉ ĉ // ĠLink čĊĉ ĉ val Ġre Link Ġ= ĠPattern . compile ( čĊĉĉ ĉ """ \ A \ ?? \[ ([ ^\ n \ [\ ]] + ? )] \ (( https ? :// [\ w / :% # @ ${ '$ '} & ?! ()\ [\ ] ~ .= + \- ]+ ? )\ ) """ čĊĉ ĉ ) čĊĉĉčĊĉ ĉ val Ġlink Parser Ġ: ĠNode Parse Env . () Ġ-> ĠNode Detected ? Ġ= Ġ{ čĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( re Link ) čĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatcher . find () Ġ-> Ġnull čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġ{ čĊĉĉĉĉ ĉ val Ġtitle Ġ= Ġmatcher . group ( 1 ) čĊĉĉĉĉ ĉ make Detected ( čĊĉĉĉĉĉ ĉ NodeType . LINK , čĊĉĉĉĉĉ ĉ array Of ( čĊĉĉĉĉĉĉ ĉ title čĊĉĉĉĉĉĉ ĉ , Ġmatcher . group ( 2 ) Ġ// Ġurl čĊĉĉĉĉĉĉ ĉ , Ġtext [ pos ]. toString () ĠĠ Ġ// Ġsilent Ġ ãģª ãĤī Ġ" ?" Ġãģ« ãģªãĤĭ čĊĉĉĉĉĉ ĉ ), čĊĉĉĉĉĉ ĉ matcher . start (), Ġmatcher . end (), čĊĉĉĉĉĉ ĉ this . text , Ġmatcher . start ( 1 ), Ġtitle . length čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ } čĊĉĉčĊĉ ĉ // Ġ[ Ġãģ¯ ãģĦ ãĤ į ãĤĵ ãģª è¦ģ ç´ł ãģ§ ä½¿ ãĤı ãĤĮãĤĭ čĊĉ ĉ // Ġsearch ãģ® åĪ¤ å®ļ ãĤĴ title ãĤĪ ãĤĬ åīį ãģ« è¡Į ãģĨ ãģĵãģ¨ ãĢĤ Ġ ãĢĮ abc Ġ[ æ¤ ľç´¢ ] Ġ ãĢį ãģ§ title ãģĮ åĦ ª åħĪ ãģķãĤĮãĤĭ ãģ¨ ãĥŀ ãĤº ãģĦ čĊĉ ĉ add Parser ("[ ", Ġsearch Parser , Ġtitle Parser , Ġlink Parser ) čĊĉ ĉ // Ġ ãģĿãģ® ä»ĸ ãģ® æĸĩåŃĹ ãģ§ ãĤĤ åĪ¤ å®ļ ãģĻãĤĭ čĊĉ ĉ add Parser (" ãĢĲ ", Ġtitle Parser ) čĊĉ ĉ add Parser (" æ¤ľ Ss ", Ġsearch Parser ) čĊĉ ĉ add Parser (" ?", Ġlink Parser ) čĊĉĉčĊĉ ĉ // Ġãĥ¡ ãĥ¼ãĥ« ãĤ¢ ãĥī ãĥ¬ ãĤ¹ ãģ® @ ãģ® æīĭ åīį ãģ« ä½¿ ãģĪãĤĭ æĸĩåŃĹ ãģª ãĤī çľŁ čĊĉ ĉ val Ġmail Chars Ġ= ĠSparse Boolean Array (). apply Ġ{ čĊĉĉ ĉ for ( it Ġin Ġ' 0 ' Ġ.. Ġ' 9 ') Ġ{ čĊĉĉĉ ĉ put ( it . toInt (), Ġtrue ) čĊĉĉ ĉ } čĊĉĉ ĉ for ( it Ġin Ġ' A ' Ġ.. Ġ' Z ') Ġ{ čĊĉĉĉ ĉ put ( it . toInt (), Ġtrue ) čĊĉĉ ĉ } čĊĉĉ ĉ for ( it Ġin Ġ' a ' Ġ.. Ġ' z ') Ġ{ čĊĉĉĉ ĉ put ( it . toInt (), Ġtrue ) čĊĉĉ ĉ } čĊĉĉ ĉ """ ${ '$ '} ! # % & '` "* +- / =? ^ _{ |} ~ """. forEach Ġ{ Ġput ( it . toInt (), Ġtrue ) Ġ} čĊĉ ĉ } čĊĉĉčĊĉ ĉ add Parser ("@ ", Ġ{ čĊĉĉĉčĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( To ot Account . re Mention ) čĊĉĉĉčĊĉĉ ĉ when Ġ{ čĊĉĉĉ ĉ ! Ġmatcher . find () Ġ-> Ġnull čĊĉĉĉĉčĊĉĉĉ ĉ else Ġ-> Ġwhen Ġ{ čĊĉĉĉĉ ĉ // Ġ çĽ´ åīį ãģ® æĸĩåŃĹ ãģĮ ãĥ¡ ãĥ¼ãĥ« ãĤ¢ ãĥī ãĥ¬ ãĤ¹ ãģ® @ ãģ® æīĭ åīį ãģ« ä½¿ ãģĪãĤĭ æĸĩåŃĹ ãģª ãĤī ãĥ¡ ãĥ³ ãĤ·ãĥ§ãĥ³ ãģ§ãģ¯ ãģªãģĦ čĊĉĉĉĉ ĉ pos Ġ> Ġ 0 Ġ&& Ġmail Chars . get ( text . code Point Before ( pos )) Ġ-> Ġnull čĊĉĉĉĉĉ čĊĉĉĉĉ ĉ else Ġ-> Ġmake Detected ( čĊĉĉĉĉĉ ĉ NodeType . MENT ION , čĊĉĉĉĉĉ ĉ array Of ( čĊĉĉĉĉĉĉ ĉ matcher . group ( 1 ), čĊĉĉĉĉĉĉ ĉ matcher . group ( 2 ) Ġ?: Ġ"" Ġ// Ġusername , Ġhost čĊĉĉĉĉĉ ĉ ), čĊĉĉĉĉĉ ĉ matcher . start (), Ġmatcher . end (), čĊĉĉĉĉĉ ĉ "", Ġ 0 , Ġ 0 čĊĉĉĉĉ ĉ ) čĊĉĉĉ ĉ } čĊĉĉ ĉ } čĊĉ ĉ }) čĊĉĉčĊĉ ĉ // ĠHas ht ag čĊĉ ĉ val Ġre Has ht ag Ġ= ĠPattern . compile (""" \ A # ([ ^\ s ., ! ? #: ]+) """) čĊĉ ĉ val Ġre Digits Only Ġ= ĠPattern . compile (""" \ A \ d *\ z """) čĊĉ ĉ add Parser ("# ", Ġ{ čĊĉĉĉčĊĉĉ ĉ if ( pos Ġ> Ġ 0 Ġ&& ĠMatcher Cache . matcher ( re Al num , Ġtext , Ġpos Ġ- Ġ 1 , Ġpos ). find ()) Ġ{ čĊĉĉĉ ĉ // Ġ çĽ´ åīį ãģ« èĭ± æķ°åŃĹ ãģĮãģĤãĤĭ ãģª ãĤī ãĤ¿ ãĤ° ãģ« ãģĹãģªãģĦ čĊĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ val Ġmatcher Ġ= Ġremain Matcher ( re Has ht ag ) čĊĉĉ ĉ if (! Ġmatcher . find ()) Ġ{ čĊĉĉĉ ĉ // ĠãĤ ¿ ãĤ° ãģ« ãĥŀ ãĥĥ ãĥģ ãģĹãģªãģĦ čĊĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ // Ġ åħĪ éł Ń ãģ® # ãĤĴ åĲ« ãģ¾ ãģªãģĦ ãĤ¿ ãĤ° ãĥĨ ãĤŃ ãĤ¹ãĥĪ čĊĉĉ ĉ val Ġtag Ġ= Ġmatcher . group ( 1 ). remove Or phan ed Br ackets () čĊĉĉĉčĊĉĉ ĉ if ( tag . isEmpty () Ġ|| Ġtag . length Ġ> Ġ 5 0 Ġ|| Ġre Digits Only . matcher ( tag ). find ()) Ġ{ čĊĉĉĉ ĉ // Ġ ç©º æĸĩåŃĹåĪĹ ãĢģ 5 0 æĸĩåŃĹ è¶ħ éģİ ãĢģ æķ°åŃĹ ãģłãģĳ ãģ® ãĤ¿ ãĤ° ãģ¯ ä¸į è¨± åı¯ čĊĉĉĉ ĉ return @ add Parser Ġnull čĊĉĉ ĉ } čĊĉĉĉčĊĉĉ ĉ make Detected ( čĊĉĉĉ ĉ NodeType . HAS HT AG , čĊĉĉĉ ĉ array Of ( tag ), čĊĉĉĉ ĉ matcher . start (), Ġmatcher . start () Ġ+ Ġ 1 Ġ+ Ġtag . length , čĊĉĉĉ ĉ "", Ġ 0 , Ġ 0 čĊĉĉ ĉ ) čĊĉ ĉ }) čĊĉĉčĊĉ ĉ // Ġcode Ġ( ãĥĸ ãĥŃ ãĥĥãĤ¯ ãĢģ ãĤ¤ãĥ³ ãĥ© ãĤ¤ãĥ³ ) čĊĉ ĉ add Parser ( čĊĉĉ ĉ "` " čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ Pattern . compile (""" \ A ``` (?: .* )\ n ([\ s \ S ]+ ? )\ n ``` (?: \ n |$ ) """) čĊĉĉĉ ĉ , ĠNode Type . CODE _ BLOCK čĊĉĉĉ ĉ /* čĊĉĉĉ ĉ ( A ) čĊĉĉĉĉ ĉ ``` code ``` Ġãģ¯ Ġ éĸ ī ãģĺ ãĤĭ éĥ¨åĪĨ ãģ® åīį å¾Į ãģ« æĶ¹ è¡Į ãģĮ ãģªãģĦ ãģ®ãģ§ ãĥĢ ãĥ¡ čĊĉĉĉ ĉ ( B ) čĊĉĉĉĉ ĉ ``` lang čĊĉĉĉĉ ĉ code čĊĉĉĉĉ ĉ code čĊĉĉĉĉ ĉ code čĊĉĉĉĉ ĉ ``` čĊĉĉĉĉ ĉ ãģ¯ lang éĥ¨åĪĨ ãģ¯ è¡¨ç¤º ãģķãĤĮ ãģªãģĦ čĊĉĉĉ ĉ ( C ) čĊĉĉĉĉ ĉ ST ãģ® è¡¨ç¤º ä¸Ĭ ãģ® éĥ½ åĲĪ ãģ§ éĸ ī ãģĺ ãĤĭ éĥ¨åĪĨ ãģ® å¾Į ãģ® æĶ¹ è¡Į ãģĮ è¤ĩ æķ° ãģĤ ãģ£ãģ¦ ãĤĤ åħ¨ ãģ¦ éĻ¤ åİ» ãģĻãĤĭ čĊĉĉĉĉ Ġ*/ čĊĉĉ ĉ ) čĊĉĉ ĉ , Ġsimple Parser ( čĊĉĉĉ ĉ // Ġ ãĤ¤ãĥ³ ãĥ© ãĤ¤ãĥ³ ãĤ³ãĥ¼ãĥī ãģ¯ åĨħéĥ¨ ãģ« ãģ¨ ãģĤãĤĭ æĸĩåŃĹ ãĤĴ åĲ« ãĤĢ ãģ¨ èªį èŃ ĺ ãģķãĤĮ ãģªãģĦ ãĢĤ çĲĨ çĶ± ãģ¯ é¡ Ķ æĸĩåŃĹ ãģ¨ è¡ Ŀ çªģ ãģĻãĤĭ ãģĭãĤī ãģł ãģ¨ ãģĭ čĊĉĉĉ ĉ Pattern . compile (""" \ A ` ([^ ` Â ´ \ x 0 d \ x 0 a ]+ )` """) čĊĉĉĉ ĉ , ĠNode Type . CODE _ INLINE čĊĉĉ ĉ ) čĊĉ ĉ ) čĊ ĉ } čĊĉčĊ ĉ // Ġãģĵãģ® ãĥķãĤ¡ãĤ¤ãĥ« ãģ® ãĤ¨ ãĥ³ãĥĪ ãĥª ãĥ¼ãĥ Ŀ ãĤ¤ãĥ³ ãĥĪ čĊ ĉ fun Ġdecode Markdown ( options Ġ: ĠDecode Options , Ġsrc Ġ: ĠString ?) Ġ= čĊĉ ĉ Sp ann able StringBuilder Ex (). apply Ġ{ čĊĉĉ ĉ val Ġsave Ġ= Ġoptions . en large Custom Emoji čĊĉĉ ĉ options . en large Custom Emoji Ġ= Ġ 2 . 5 f čĊĉĉ ĉ try Ġ{ čĊĉĉĉ ĉ val Ġenv Ġ= ĠSpan Output Env ( options , Ġthis ) čĊĉĉĉĉčĊĉĉĉ ĉ if ( src Ġ!= Ġnull ) Ġ{ čĊĉĉĉĉ ĉ val Ġroot Ġ= ĠNode ( NodeType . ROOT , Ġempty Array (), Ġnull ) čĊĉĉĉĉ ĉ Node Parse Env ( root , Ġsrc , Ġ 0 , Ġsrc . length ). parse Inside () čĊĉĉĉĉ ĉ env . fire Render ( root ). set Span ( env . sb ) čĊĉĉĉĉĉ čĊĉĉĉ ĉ } čĊĉĉĉĉčĊĉĉĉ ĉ // Ġ æľ« å°¾ ãģ® ç©º çĻ½ ãĤĴ åıĸ ãĤĬ éĻ¤ ãģı čĊĉĉĉ ĉ val Ġend Ġ= Ġlength čĊĉĉĉ ĉ var Ġpos Ġ= Ġend čĊĉĉĉ ĉ while ( pos Ġ> Ġ 0 Ġ&& ĠHTML Decoder . is Whitespace Or Line Feed ( get ( pos Ġ- Ġ 1 ). toInt ())) Ġ-- Ġpos čĊĉĉĉ ĉ if ( pos Ġ< Ġend ) Ġdelete ( pos , Ġend ) čĊĉĉĉĉ čĊĉĉ ĉ } Ġcatch ( ex Ġ: ĠThrowable ) Ġ{ čĊĉĉĉ ĉ log . trace ( ex ) čĊĉĉĉ ĉ log . e ( ex , Ġ" decode Markdown Ġfailed ") čĊĉĉ ĉ } Ġfinally Ġ{ čĊĉĉĉ ĉ options . en large Custom Emoji Ġ= Ġsave čĊĉĉ ĉ } čĊĉ ĉ } č Ċ } čĊ