/* Ċ Ġ* ĠReading Time . kt Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 - 2 0 2 1 , ĠE rik ĠC . ĠTh au vin Ġ( erik @ th au vin . net ) Ċ Ġ* ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠRedistribution Ġand Ġuse Ġin Ġsource Ġand Ġbinary Ġforms , Ġwith Ġor Ġwithout Ċ Ġ* Ġmodification , Ġare Ġpermitted Ġprovided Ġthat Ġthe Ġfollowing Ġconditions Ġare Ġmet : Ċ Ġ* Ċ Ġ* ĠĠ ĠRedistributions Ġof Ġsource Ġcode Ġmust Ġretain Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer . Ċ Ġ* Ċ Ġ* ĠĠ ĠRedistributions Ġin Ġbinary Ġform Ġmust Ġreproduce Ġthe Ġabove Ġcopyright Ġnotice , Ċ Ġ* ĠĠ Ġthis Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer Ġin Ġthe Ġdocumentation Ċ Ġ* ĠĠ Ġand / or Ġother Ġmaterials Ġprovided Ġwith Ġthe Ġdistribution . Ċ Ġ* Ċ Ġ* ĠĠ ĠNeither Ġthe Ġname Ġof Ġthis Ġproject Ġnor Ġthe Ġnames Ġof Ġits Ġcontributors Ġmay Ġbe Ċ Ġ* ĠĠ Ġused Ġto Ġendorse Ġor Ġpromote Ġproducts Ġderived Ġfrom Ġthis Ġsoftware Ġwithout Ċ Ġ* ĠĠ Ġspecific Ġprior Ġwritten Ġpermission . Ċ Ġ* Ċ Ġ* ĠTHIS ĠSOFTWARE ĠIS ĠPROVIDED ĠBY ĠTHE ĠCOPYRIGHT ĠHOLDERS ĠAND ĠCONTRIBUTORS Ġ" AS ĠIS " Ċ Ġ* ĠAND ĠANY ĠEXPRESS ĠOR ĠIMPLIED ĠWARRANTIES , ĠINCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠTHE Ċ Ġ* ĠIMPLIED ĠWARRANTIES ĠOF ĠMERCHANTABILITY ĠAND ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠARE Ċ Ġ* ĠDISCLAIMED . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠCOPYRIGHT ĠHOLDER ĠOR ĠCONTRIBUTORS ĠBE ĠLIABLE Ċ Ġ* ĠFOR ĠANY ĠDIRECT , ĠINDIRECT , ĠINCIDENTAL , ĠSPECIAL , ĠEXEMPLARY , ĠOR ĠCONSEQUENTIAL Ċ Ġ* ĠDAMAGES Ġ( INCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠPROCUREMENT ĠOF ĠSUBSTITUTE ĠGOODS ĠOR Ċ Ġ* ĠSERVICES ; ĠLOSS ĠOF ĠUSE , ĠDATA , ĠOR ĠPROFITS ; ĠOR ĠBUSINESS ĠINTERRUPTION ) ĠHOWEVER Ċ Ġ* ĠCAUSED ĠAND ĠON ĠANY ĠTHEORY ĠOF ĠLIABILITY , ĠWHETHER ĠIN ĠCONTRACT , ĠSTRICT ĠLIABILITY , Ċ Ġ* ĠOR ĠTORT Ġ( INCLUDING ĠNEGLIGENCE ĠOR ĠOTHERWISE ) ĠARISING ĠIN ĠANY ĠWAY ĠOUT ĠOF ĠTHE ĠUSE Ċ Ġ* ĠOF ĠTHIS ĠSOFTWARE , ĠEVEN ĠIF ĠADVISED ĠOF ĠTHE ĠPOSSIBILITY ĠOF ĠSUCH ĠDAMAGE . Ċ Ġ*/ Ċ Ċ package Ġnet . th au vin . erik . reading time Ċ Ċ import Ġorg . js oup . J soup Ċ import Ġjava . math . BigDecimal Ċ import Ġjava . math . Round ingMode Ċ Ċ /** Ċ Ġ* ĠCalculates Ġthe Ġreading Ġtime Ġof Ġthe Ġgiven Ġ[ text ]. Ċ Ġ* Ċ Ġ* ĠBased Ġon Ġ[ Medium 's Ġcalculation ]( https :// blog . medium . com / read - time - and - you - bc 2 0 4 8 ab 6 2 0 c ). Ċ Ġ* Ċ Ġ* Ġ@ param Ġtext ĠThe Ġtext Ġto Ġbe Ġevaluated . Ċ Ġ* Ġ@ param Ġw pm ĠThe Ġwords Ġper Ġminute Ġreading Ġaverage . Ċ Ġ* Ġ@ param Ġpostfix ĠThe Ġvalue Ġto Ġbe Ġappended Ġto Ġthe Ġreading Ġtime . Ċ Ġ* Ġ@ param Ġplural ĠThe Ġvalue Ġto Ġbe Ġappended Ġif Ġthe Ġreading Ġtime Ġis Ġmore Ġthan Ġ 1 Ġminute . Ċ Ġ* Ġ@ param Ġexclude Images ĠImages Ġare Ġexcluded Ġfrom Ġthe Ġreading Ġtime Ġwhen Ġset . Ċ Ġ* Ġ@ param Ġextra ĠAdditional Ġseconds Ġto Ġbe Ġadded Ġto Ġthe Ġtotal Ġreading Ġtime . Ċ Ġ*/ Ċ class ĠReading Time Ġ@ Jvm Over loads Ġconstructor ( ĊĠĠĠ Ġtext : ĠString , ĊĠĠĠ Ġw pm : ĠInt Ġ= Ġ 2 7 5 , ĊĠĠĠ Ġvar Ġpostfix : ĠString Ġ= Ġ" min Ġread ", ĊĠĠĠ Ġvar Ġplural : ĠString Ġ= Ġ" min Ġread ", ĊĠĠĠ Ġexclude Images : ĠBoolean Ġ= Ġfalse , ĊĠĠĠ Ġextra : ĠInt Ġ= Ġ 0 Ċ ) Ġ{ ĠĠĠĠĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠINVALID : ĠDouble Ġ= Ġ- 1 . 0 ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCount s Ġwords . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠHTML Ġtags Ġare Ġstripped . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġword Count ( words : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs Ġ= ĠJ soup . parse ( words ). text (). trim () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( s . isBlank ()) Ġ 0 Ġelse Ġs . split ("\\ s +". to Regex ()). size ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCount s ĠHTML Ġimg Ġtags . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġimg Count ( html : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ"< img Ġ". to Regex ( Regex Option . IGNORE _ CASE ). findAll ( html ). count () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġread Time : ĠDouble Ġ= ĠINVALID ĊĊĠĠĠ Ġvar Ġtext : ĠString Ġ= Ġtext ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( value Ġ!= Ġtext ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġw pm : ĠInt Ġ= Ġw pm ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( value Ġ!= Ġw pm ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġexclude Images : ĠBoolean Ġ= Ġexclude Images ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( value Ġ!= Ġexclude Images ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġextra : ĠInt Ġ= Ġextra ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset ( value Ġ!= Ġextra ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalculates Ġand Ġreturns Ġthe Ġreading Ġtime Ġin Ġseconds . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcalc Reading TimeIn Sec (): ĠDouble Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( read Time Ġ== ĠINVALID ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Time Ġ= Ġif Ġ(! exclude Images ) Ġcalc Img Reading Time (). toDouble () Ġelse Ġ 0 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Time Ġ+= Ġ( word Count ( text ) Ġ/ Ġw pm ) Ġ* Ġ 6 0 . 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġread Time Ġ+ Ġextra ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalculates Ġand Ġreturns Ġthe Ġreading Ġtime . Ġ( eg . Ġ 1 Ġmin Ġread ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcalc Reading Time (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtime Ġ= ĠBigDecimal (( calc Reading TimeIn Sec () Ġ/ Ġ 6 0 . 0 )). set Scale ( 0 , ĠRound ingMode . HALF _ DOWN ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( time . compareTo ( BigDecimal . ONE ) Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ time Ġ$ plural ". trim () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ time Ġ$ postfix ". trim () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcalc Img Reading Time (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtime Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġimg Count Ġ= Ġimg Count ( text ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġoffset Ġ= Ġ 1 2 ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. img Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ> Ġ 1 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Ġ+= Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Ġ+= Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtime ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreset ( is Changed : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Changed ) Ġread Time Ġ= ĠINVALID ĊĠĠĠ Ġ} Ċ } Ċ