Added round parameter. Closes #1
This commit is contained in:
parent
d99218f43b
commit
6cabd2e723
7 changed files with 102 additions and 93 deletions
34
README.md
34
README.md
|
@ -22,7 +22,17 @@ To get the estimated reading time in seconds use the `calcReadingTimeInSec()` fu
|
|||
|
||||
- View [Kotlin](https://github.com/ethauvin/readingtime/blob/master/examples/src/main/kotlin/com/example/ReadingTimeExample.kt) or [Java](https://github.com/ethauvin/readingtime/blob/master/examples/src/main/java/com/example/ReadingTimeSample.java) Examples.
|
||||
|
||||
### Gradle, Maven, etc.
|
||||
|
||||
To use with [Gradle](https://gradle.org/), include the following dependency in your [build](https://github.com/ethauvin/readingtime/blob/master/examples/build.gradle.kts) file:
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
implementation("net.thauvin.erik:readingtime:0.9.1")
|
||||
}
|
||||
```
|
||||
|
||||
Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/artifact/net.thauvin.erik/readingtime/0.9.0/jar).
|
||||
|
||||
### Properties
|
||||
|
||||
|
@ -30,24 +40,26 @@ The following properties are available:
|
|||
|
||||
```kotlin
|
||||
ReadingTime(
|
||||
text = "some_text",
|
||||
text,
|
||||
wpm = 275,
|
||||
postfix = "min read",
|
||||
plural = "min read",
|
||||
excludeImages = false,
|
||||
extra = 0
|
||||
extra = 0,
|
||||
round = RoundingMode.HALF_DOWN
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
Property | Description
|
||||
:-------------------------- |:-------------------------------------------------------------------
|
||||
`text` | The text to be evaluated.
|
||||
Property | Description
|
||||
:-------------------------- |:-----------------------------------------------------------------------------------------------------------------------
|
||||
`text` | The text to be evaluated. (Required)
|
||||
`wpm` | The words per minute reading average.
|
||||
`postfix` | The value to be appended to the reading time.
|
||||
`plural` | The value to be appended if the reading time is more than 1 minute.
|
||||
`excludeImages` | Images are excluded from the reading time when set.
|
||||
`extra` | Additional seconds to be added to the total reading time.
|
||||
`round` | The [rounding mode](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/RoundingMode.html) to apply.
|
||||
|
||||
### Functions
|
||||
|
||||
|
@ -73,15 +85,3 @@ A JSP tag is also available for easy incorporation into web applications:
|
|||
```
|
||||
|
||||
None of the attributes are required.
|
||||
|
||||
### Gradle, Maven, etc.
|
||||
|
||||
To use with [Gradle](https://gradle.org/), include the following dependency in your [build](https://github.com/ethauvin/readingtime/blob/master/examples/build.gradle.kts) file:
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
implementation("net.thauvin.erik:readingtime:0.9.0")
|
||||
}
|
||||
```
|
||||
|
||||
Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/artifact/net.thauvin.erik/readingtime/0.9.0/jar).
|
||||
|
|
|
@ -6,16 +6,16 @@ import java.io.FileInputStream
|
|||
import java.util.*
|
||||
|
||||
plugins {
|
||||
id("com.github.ben-manes.versions") version "0.38.0"
|
||||
id("com.github.ben-manes.versions") version "0.39.0"
|
||||
id("io.gitlab.arturbosch.detekt") version "1.17.1"
|
||||
id("jacoco")
|
||||
id("java")
|
||||
id("java-library")
|
||||
id("maven-publish")
|
||||
id("org.jetbrains.dokka") version "1.4.32"
|
||||
id("org.jetbrains.kotlin.jvm") version "1.5.0"
|
||||
id("org.sonarqube") version "3.2.0"
|
||||
java
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
jacoco
|
||||
signing
|
||||
id("signing")
|
||||
kotlin("jvm") version "1.5.10"
|
||||
}
|
||||
|
||||
description = "Estimated Reading Time for Blog Posts, Articles, etc."
|
||||
|
@ -34,12 +34,12 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
||||
implementation(platform(kotlin("bom")))
|
||||
|
||||
implementation("org.jsoup:jsoup:1.13.1")
|
||||
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
|
||||
testImplementation(kotlin("test"))
|
||||
testImplementation(kotlin("test-junit"))
|
||||
}
|
||||
|
||||
java {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" ?>
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>LongParameterList:ReadingTime.kt$ReadingTime$( text: String, wpm: Int = 275, var postfix: String = "min read", var plural: String = "min read", excludeImages: Boolean = false, extra: Int = 0, var round: RoundingMode = RoundingMode.HALF_DOWN )</ID>
|
||||
<ID>MagicNumber:ReadingTime.kt$ReadingTime$10</ID>
|
||||
<ID>MagicNumber:ReadingTime.kt$ReadingTime$12</ID>
|
||||
<ID>MagicNumber:ReadingTime.kt$ReadingTime$3</ID>
|
||||
<ID>MagicNumber:ReadingTime.kt$ReadingTime$60</ID>
|
||||
<ID>MagicNumber:ReadingTime.kt$ReadingTime$60.0</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
plugins {
|
||||
id("org.jetbrains.kotlin.jvm") version "1.5.0"
|
||||
id("com.github.ben-manes.versions") version "0.38.0"
|
||||
application
|
||||
id("application")
|
||||
id("com.github.ben-manes.versions") version "0.39.0"
|
||||
kotlin("jvm") version "1.5.10"
|
||||
}
|
||||
|
||||
// ./gradlew run
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -40,7 +40,7 @@
|
|||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-bom</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<version>1.5.10</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
@ -50,7 +50,7 @@
|
|||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<version>1.5.10</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -49,6 +49,7 @@ import java.math.RoundingMode
|
|||
* @param plural The value to be appended if the reading time is more than 1 minute.
|
||||
* @param excludeImages Images are excluded from the reading time when set.
|
||||
* @param extra Additional seconds to be added to the total reading time.
|
||||
* @param round The [RoundingMode] to apply. Default is [RoundingMode.HALF_DOWN].
|
||||
*/
|
||||
class ReadingTime @JvmOverloads constructor(
|
||||
text: String,
|
||||
|
@ -56,7 +57,8 @@ class ReadingTime @JvmOverloads constructor(
|
|||
var postfix: String = "min read",
|
||||
var plural: String = "min read",
|
||||
excludeImages: Boolean = false,
|
||||
extra: Int = 0
|
||||
extra: Int = 0,
|
||||
var round: RoundingMode = RoundingMode.HALF_DOWN
|
||||
) {
|
||||
companion object {
|
||||
private const val INVALID: Double = -1.0
|
||||
|
@ -108,7 +110,9 @@ class ReadingTime @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculates and returns the reading time in seconds.
|
||||
* Calculates and returns the reading time in seconds.
|
||||
*
|
||||
* `((word count / wpm) * 60) + images + extra`
|
||||
*/
|
||||
fun calcReadingTimeInSec(): Double {
|
||||
if (readTime == INVALID) {
|
||||
|
@ -121,9 +125,11 @@ class ReadingTime @JvmOverloads constructor(
|
|||
|
||||
/**
|
||||
* Calculates and returns the reading time. (eg. 1 min read)
|
||||
*
|
||||
* `(reading time in sec / 60) + postfix`
|
||||
*/
|
||||
fun calcReadingTime(): String {
|
||||
val time = BigDecimal((calcReadingTimeInSec() / 60.0)).setScale(0, RoundingMode.HALF_DOWN)
|
||||
val time = BigDecimal((calcReadingTimeInSec() / 60.0)).setScale(0, round)
|
||||
return if (time.compareTo(BigDecimal.ONE) == 1) {
|
||||
"$time $plural".trim()
|
||||
} else {
|
||||
|
@ -131,6 +137,10 @@ class ReadingTime @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 12 seconds for the first image, 11 for the second, and minus an additional second for each subsequent image.
|
||||
* Any images after the tenth image are counted at 3 seconds.
|
||||
*/
|
||||
private fun calcImgReadingTime(): Int {
|
||||
var time = 0
|
||||
val imgCount = imgCount(text)
|
||||
|
|
|
@ -33,28 +33,16 @@
|
|||
package net.thauvin.erik.readingtime
|
||||
|
||||
import java.io.File
|
||||
import java.math.RoundingMode
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ReadingTimeTest {
|
||||
private val rt = ReadingTime("This is a <b>test</b>.\nWith an image: <img src=\"#\">")
|
||||
private val img = """<img src="#">"""
|
||||
private val rt = ReadingTime("This is a <b>test</b>.\nWith an image: $img")
|
||||
private val blogPost = File("src/test/resources/post.html").readText()
|
||||
private val mediumPost = File("src/test/resources/medium.html").readText()
|
||||
private val twoSeventyFive = """one two three four five six seven eight nine ten one two three four five six seven
|
||||
eight nine ten one two three four five six seven eight nine ten one two three four five six seven eight nine
|
||||
ten one two three four five six seven eight nine ten one two three four five six seven eight nine ten one two
|
||||
three four five six seven eight nine ten one two three four five six seven eight nine ten one two three four
|
||||
five six seven eight nine ten one two three four five six seven eight nine ten one two three four five six
|
||||
seven eight nine ten one two three four five six seven eight nine ten one two three four five six seven eight
|
||||
nine ten one two three four five six seven eight nine ten one two three four five six seven eight nine ten
|
||||
one two three four five six seven eight nine ten one two three four five six seven eight nine ten one two
|
||||
three four five six seven eight nine ten one two three four five six seven eight nine ten one two three four
|
||||
five six seven eight nine ten one two three four five six seven eight nine ten one two three four five six
|
||||
seven eight nine ten one two three four five six seven eight nine ten one two three four five six seven eight
|
||||
nine ten one two three four five six seven eight nine ten one two three four five six seven eight nine ten
|
||||
one two three four five six seven eight nine ten one two three four five"""
|
||||
private val tenImages = "<img src=\"#\"> <img src=\"#\"> <img src=\"#\"> <img src=\"#\"> <img src=\"#\"> " +
|
||||
"<img src=\"#\"> <img src=\"#\"> <img src=\"#\"> <img src=\"#\"> <img src=\"#\">"
|
||||
private val twoSeventyFive = "word ".repeat(275)
|
||||
|
||||
private fun calcImgTime(imgCount: Int): Double {
|
||||
var time = 0.0
|
||||
|
@ -75,100 +63,111 @@ one two three four five six seven eight nine ten one two three four five"""
|
|||
|
||||
@Test
|
||||
fun testWordCount() {
|
||||
assertEquals(0, ReadingTime.wordCount(" "))
|
||||
assertEquals(3, ReadingTime.wordCount("one two three"))
|
||||
assertEquals(2, ReadingTime.wordCount(" one two "))
|
||||
assertEquals(7, ReadingTime.wordCount(rt.text))
|
||||
assertEquals(505, ReadingTime.wordCount(blogPost))
|
||||
assertEquals(391, ReadingTime.wordCount(mediumPost))
|
||||
assertEquals(275, ReadingTime.wordCount(twoSeventyFive))
|
||||
assertEquals(275, ReadingTime.wordCount("$twoSeventyFive <img src=\"#\""))
|
||||
assertEquals(0, ReadingTime.wordCount(" "), "empty")
|
||||
assertEquals(3, ReadingTime.wordCount("one two three"), "one two three")
|
||||
assertEquals(2, ReadingTime.wordCount(" one two "), "one two")
|
||||
assertEquals(7, ReadingTime.wordCount(rt.text), "text")
|
||||
assertEquals(505, ReadingTime.wordCount(blogPost), "blogPost")
|
||||
assertEquals(391, ReadingTime.wordCount(mediumPost), "mediumPost")
|
||||
assertEquals(275, ReadingTime.wordCount(twoSeventyFive), "275")
|
||||
assertEquals(275, ReadingTime.wordCount("$twoSeventyFive $img"), "275 + image")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testImgCount() {
|
||||
assertEquals(1, ReadingTime.imgCount(rt.text))
|
||||
assertEquals(11, ReadingTime.imgCount(blogPost))
|
||||
assertEquals(3, ReadingTime.imgCount(mediumPost))
|
||||
assertEquals(1, ReadingTime.imgCount("$twoSeventyFive <img src=\"#\""))
|
||||
assertEquals(2, ReadingTime.imgCount("$twoSeventyFive <img src=\"#\"> <img src=\"#\">"))
|
||||
assertEquals(1, ReadingTime.imgCount(rt.text), "text")
|
||||
assertEquals(11, ReadingTime.imgCount(blogPost), "blogPost")
|
||||
assertEquals(3, ReadingTime.imgCount(mediumPost), "mediumPost")
|
||||
assertEquals(1, ReadingTime.imgCount("$twoSeventyFive $img"), "275 + image")
|
||||
assertEquals(2, ReadingTime.imgCount("$twoSeventyFive $img $img"), "275 + 2 images")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReadingTimeInSec() {
|
||||
assertEquals(calcReadingTime(rt.text, rt.wpm) + calcImgTime(1), rt.calcReadingTimeInSec())
|
||||
assertEquals(calcReadingTime(rt.text, rt.wpm) + calcImgTime(1), rt.calcReadingTimeInSec(), "text + image")
|
||||
|
||||
rt.text = "<img src=\"#\"> <IMG src=\"#\">"
|
||||
assertEquals(calcImgTime(2), rt.calcReadingTimeInSec())
|
||||
rt.text = "$img ${img.uppercase()}"
|
||||
assertEquals(calcImgTime(2), rt.calcReadingTimeInSec(), "2 images")
|
||||
rt.excludeImages = true
|
||||
assertEquals(0.0, rt.calcReadingTimeInSec())
|
||||
assertEquals(0.0, rt.calcReadingTimeInSec(), "image uppercase")
|
||||
rt.excludeImages = false
|
||||
|
||||
rt.text = blogPost
|
||||
assertEquals(
|
||||
calcReadingTime(rt.text, rt.wpm) + calcImgTime(11), rt.calcReadingTimeInSec()
|
||||
calcReadingTime(rt.text, rt.wpm) + calcImgTime(11), rt.calcReadingTimeInSec(), "blogPost"
|
||||
)
|
||||
|
||||
rt.excludeImages = true
|
||||
assertEquals(calcReadingTime(rt.text, rt.wpm), rt.calcReadingTimeInSec())
|
||||
assertEquals(calcReadingTime(rt.text, rt.wpm), rt.calcReadingTimeInSec(), "exclude images")
|
||||
rt.extra = 60
|
||||
assertEquals(calcReadingTime(rt.text, rt.wpm) + 60L, rt.calcReadingTimeInSec())
|
||||
assertEquals(calcReadingTime(rt.text, rt.wpm) + 60L, rt.calcReadingTimeInSec(), "extra 60")
|
||||
rt.extra = 0
|
||||
rt.excludeImages = false
|
||||
|
||||
rt.text = mediumPost
|
||||
rt.wpm = 300
|
||||
assertEquals(calcReadingTime(rt.text, 300) + calcImgTime(3), rt.calcReadingTimeInSec())
|
||||
assertEquals(calcReadingTime(rt.text, 300) + calcImgTime(3), rt.calcReadingTimeInSec(), "mediumPost 300 wpm")
|
||||
rt.wpm = 275
|
||||
|
||||
rt.text = "This is a test"
|
||||
assertEquals(0.0, rt.calcReadingTimeInSec())
|
||||
assertEquals(0.0, rt.calcReadingTimeInSec(), "test")
|
||||
|
||||
rt.text = twoSeventyFive
|
||||
assertEquals(60.0, rt.calcReadingTimeInSec())
|
||||
assertEquals(60.0, rt.calcReadingTimeInSec(), "275")
|
||||
|
||||
rt.text = "$twoSeventyFive <img src=\"#\">"
|
||||
assertEquals(72.0, rt.calcReadingTimeInSec())
|
||||
rt.text = "$twoSeventyFive $img"
|
||||
assertEquals(72.0, rt.calcReadingTimeInSec(), "275 + image")
|
||||
|
||||
rt.text = "$twoSeventyFive <img src=\"#\"> <img src=\"#\">"
|
||||
assertEquals(83.0, rt.calcReadingTimeInSec())
|
||||
rt.text = "$twoSeventyFive $img $img"
|
||||
assertEquals(83.0, rt.calcReadingTimeInSec(), "275 + 2 images")
|
||||
|
||||
rt.text = "$twoSeventyFive $tenImages"
|
||||
assertEquals(60.0 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3, rt.calcReadingTimeInSec())
|
||||
rt.text = "$twoSeventyFive ${img.repeat(10)}"
|
||||
assertEquals(60.0 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3, rt.calcReadingTimeInSec(), "10 images")
|
||||
|
||||
rt.text = "$twoSeventyFive $tenImages <img src=\"#\">"
|
||||
assertEquals(135.0 + 3, rt.calcReadingTimeInSec())
|
||||
rt.text = "$twoSeventyFive ${img.repeat(10)} $img"
|
||||
assertEquals(135.0 + 3, rt.calcReadingTimeInSec(), "11 images")
|
||||
|
||||
rt.text = "$twoSeventyFive $twoSeventyFive"
|
||||
assertEquals(120.0, rt.calcReadingTimeInSec())
|
||||
assertEquals(120.0, rt.calcReadingTimeInSec(), "275*2")
|
||||
|
||||
rt.text = ""
|
||||
assertEquals(0.0, rt.calcReadingTimeInSec())
|
||||
assertEquals(0.0, rt.calcReadingTimeInSec(), "empty")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReadingTime() {
|
||||
rt.text = blogPost
|
||||
assertEquals("2 min read", rt.calcReadingTime())
|
||||
assertEquals("2 min read", rt.calcReadingTime(), "blogPost")
|
||||
|
||||
rt.plural = "mins read"
|
||||
assertEquals("2 mins read", rt.calcReadingTime())
|
||||
assertEquals("2 mins read", rt.calcReadingTime(), "plural")
|
||||
|
||||
rt.text = mediumPost
|
||||
rt.plural = ""
|
||||
assertEquals("2", rt.calcReadingTime())
|
||||
assertEquals("2", rt.calcReadingTime(), "mediumPost")
|
||||
|
||||
rt.text = "This is a test."
|
||||
rt.postfix = ""
|
||||
assertEquals("0", rt.calcReadingTime())
|
||||
assertEquals("0", rt.calcReadingTime(), "test")
|
||||
|
||||
rt.text = ""
|
||||
assertEquals("0", rt.calcReadingTime())
|
||||
assertEquals("0", rt.calcReadingTime(), "empty")
|
||||
|
||||
rt.text = twoSeventyFive
|
||||
assertEquals("1", rt.calcReadingTime())
|
||||
assertEquals("1", rt.calcReadingTime(), "275")
|
||||
|
||||
rt.text = "$twoSeventyFive $twoSeventyFive"
|
||||
assertEquals("2", rt.calcReadingTime())
|
||||
assertEquals("2", rt.calcReadingTime(), "275 * 2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRoundingMode() {
|
||||
rt.text = blogPost
|
||||
rt.round = RoundingMode.UP
|
||||
assertEquals("3 min read", rt.calcReadingTime(), "UP")
|
||||
|
||||
rt.text = mediumPost
|
||||
rt.round = RoundingMode.DOWN
|
||||
assertEquals("1 min read", rt.calcReadingTime(), "DOWN")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue