\ No newline at end of file
diff --git a/.idea/intellij-javadocs-4.0.1.xml b/.idea/intellij-javadocs-4.0.1.xml
new file mode 100644
index 0000000..3ed9781
--- /dev/null
+++ b/.idea/intellij-javadocs-4.0.1.xml
@@ -0,0 +1,204 @@
+
+
+
+
+ UPDATE
+ false
+ true
+
+ METHOD
+ TYPE
+ FIELD
+
+
+ DEFAULT
+ PUBLIC
+ PROTECTED
+
+
+
+
+
+ ^.*(public|protected|private)*.+interface\s+\w+.*
+ /**\n
+ * The interface ${name}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+ */
+
+
+ ^.*(public|protected|private)*.+enum\s+\w+.*
+ /**\n
+ * The enum ${name}.\n
+ */
+
+
+ ^.*(public|protected|private)*.+class\s+\w+.*
+ /**\n
+ * The type ${name}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+ */
+
+
+ .+
+ /**\n
+ * The type ${name}.\n
+ */
+
+
+
+
+ .+
+ /**\n
+ * Instantiates a new ${name}.\n
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+
+
+ ^.*(public|protected|private)*\s*.*(\w(\s*<.+>)*)+\s+get\w+\s*\(.*\).+
+ /**\n
+ * Gets ${partName}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${partName}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ ^.*(public|protected|private)*\s*.*(void|\w(\s*<.+>)*)+\s+set\w+\s*\(.*\).+
+ /**\n
+ * Sets ${partName}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${partName}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ ^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+
+ /**\n
+ * The entry point of application.\n
+
+ <#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+ * @param ${element.parameterList.parameters[0].name} the input arguments\n
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ .+
+ /**\n
+ * ${name}<#if isNotVoid> ${return}</#if>.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${return}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+
+
+ ^.*(public|protected|private)*.+static.*(\w\s\w)+.+
+ /**\n
+ * The constant ${element.getName()}.\n
+ */
+
+
+ ^.*(public|protected|private)*.*(\w\s\w)+.+
+ /**\n
+ <#if element.parent.isInterface()>
+ * The constant ${element.getName()}.\n
+<#else>
+ * The ${name}.\n
+</#if> */
+
+
+ .+
+ /**\n
+ <#if element.parent.isEnum()>
+ *${name} ${typeName}.\n
+<#else>
+ * The ${name}.\n
+</#if>*/
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml
deleted file mode 100644
index bc444de..0000000
--- a/.idea/kotlinScripting.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml
new file mode 100644
index 0000000..153a060
--- /dev/null
+++ b/.idea/libraries/bld.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/libraries/compile.xml b/.idea/libraries/compile.xml
new file mode 100644
index 0000000..99cc0c0
--- /dev/null
+++ b/.idea/libraries/compile.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/runtime.xml b/.idea/libraries/runtime.xml
new file mode 100644
index 0000000..d4069f2
--- /dev/null
+++ b/.idea/libraries/runtime.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/test.xml b/.idea/libraries/test.xml
new file mode 100644
index 0000000..57ed5ef
--- /dev/null
+++ b/.idea/libraries/test.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index fe5a948..96b0faa 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,5 +1,32 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..55adcb9
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Run Tests.xml b/.idea/runConfigurations/Run Tests.xml
new file mode 100644
index 0000000..068d7e9
--- /dev/null
+++ b/.idea/runConfigurations/Run Tests.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c709d84..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-language: java
-dist: trusty
-
-env:
- global:
- - CI=true
-
-#install:
-# - git fetch --unshallow --tags
-
-addons:
- sonarcloud:
- organization: "ethauvin-github"
-
-jdk:
- - oraclejdk8
- - openjdk15
-
-before_install:
- - chmod +x gradlew
-
-after_success:
- - |
- if [ "${TRAVIS_TEST_RESULT}" == 0 ] && [ "$TRAVIS_JDK_VERSION" == "openjdk15" ]; then
- ./gradlew sonarqube
- fi
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..ae95f51
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "java",
+ "name": "Run Tests",
+ "request": "launch",
+ "mainClass": "net.thauvin.erik.ReadingTimeTest"
+ }
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..ba429d0
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,15 @@
+{
+ "java.project.sourcePaths": [
+ "src/main/java",
+ "src/main/resources",
+ "src/test/java",
+ "src/test/resources",
+ "src/bld/java",
+ "src/bld/resources"
+ ],
+ "java.configuration.updateBuildConfiguration": "automatic",
+ "java.project.referencedLibraries": [
+ "${HOME}/.bld/dist/bld-2.2.1.jar",
+ "lib/**/*.jar"
+ ]
+}
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 15551d4..8af7d8e 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,4 +1,4 @@
-Copyright (c) 2020-2021, Erik C. Thauvin (erik@thauvin.net)
+Copyright (c) 2020-2025, Erik C. Thauvin (erik@thauvin.net)
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index f13afd8..7a41220 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,18 @@
-[](http://opensource.org/licenses/BSD-3-Clause) [](https://github.com/ethauvin/readingtime/releases/latest) [](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/readingtime)
+[](https://opensource.org/licenses/BSD-3-Clause)
+[](https://kotlinlang.org/)
+[](https://rife2.com/bld)
+[](https://github.com/ethauvin/readingtime/releases/latest)
+[](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22readingtime%22)
+[](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/readingtime/)
-[](https://snyk.io/test/github/ethauvin/readingtime?targetFile=pom.xml) [](https://sonarcloud.io/dashboard?id=ethauvin_readingtime) [](https://travis-ci.com/ethauvin/readingtime) [](https://circleci.com/gh/ethauvin/readingtime/tree/master)
+
+[](https://sonarcloud.io/dashboard?id=ethauvin_readingtime)
+[](https://github.com/ethauvin/readingtime/actions/workflows/bld.yml)
+[](https://circleci.com/gh/ethauvin/readingtime/tree/master)
# Estimated Reading Time for Blog Posts, Articles, etc.
-A simple Kotlin/Java implementation of [Medium's Read Time calculation](https://blog.medium.com/read-time-and-you-bc2048ab620c).
+A simple implementation of [Medium's Read Time calculation](https://blog.medium.com/read-time-and-you-bc2048ab620c).
## Examples (TL;DR)
@@ -18,38 +26,67 @@ println(rt.calcEstimatedReadTime()) // eg: 2 min read
```
+- View [bld](https://github.com/ethauvin/readingtime/blob/master/examples/bld) or [Gradle](https://github.com/ethauvin/readingtime/blob/master/examples/gradle) Examples
+
To get the estimated reading time in seconds use the `calcReadingTimeInSec()` function.
- - 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.
+## bld
+To use with [bld](https://rife2.com/bld), include the following dependency in your [build](https://github.com/ethauvin/readingtime/blob/master/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java) file:
+```java
+repositories = List.of(MAVEN_CENTRAL);
-### Properties
+scope(compile)
+ .include(dependency("net.thauvin.erik:readingtime:0.9.2"));
+```
+
+Be sure to use the [bld Kotlin extension](https://github.com/rife2/bld-kotlin) in your project.
+
+### 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/gradle/build.gradle.kts) file:
+
+```gradle
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("net.thauvin.erik:readingtime:0.9.2")
+}
+```
+
+Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22readingtime%22).
+
+## Properties
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,
+ roundingMode = RoundingMode.HALF_EVEN
)
```
-Property | Description
-:-------------------------- |:-------------------------------------------------------------------
-`text` | The text to be evaluated.
-`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.
+| 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. |
+| `roundingMode` | The [rounding mode](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/RoundingMode.html) to apply. |
-### Functions
+## Functions
A couple of useful functions are also available:
@@ -58,7 +95,7 @@ ReadingTime.wordCount(htmlText) // Returns the count of words. (HTML stripped)
ReadingTime.imgCount(htmlText) // Returns the count of images. (HTML img tags)
```
-### JSP
+## JSP
A JSP tag is also available for easy incorporation into web applications:
@@ -74,18 +111,41 @@ A JSP tag is also available for easy incorporation into web applications:
None of the attributes are required.
-### Gradle, Maven, etc.
+## Java
-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:
+In addition to setters, a configuration builder is also available:
-```gradle
-repositories {
- jcenter()
-}
-
-dependencies {
- implementation("net.thauvin.erik:readingtime:0.9.0")
-}
+```java
+final ReadingTime rt = new ReadingTime(text);
+rt.setPostfix("minute to read");
+rt.setPlural("minutes to read");
```
-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).
+or
+
+```java
+final Config config =
+ new Config.Builder(text)
+ .postfix("minute to read")
+ .plural("minutes to read")
+ .build();
+final ReadingTime rt = new ReadingTime(config);
+```
+
+## Contributing
+
+If you want to contribute to this project, all you have to do is clone the GitHub
+repository:
+
+```console
+git clone git@github.com:ethauvin/readingtime.git
+```
+
+Then use [bld](https://rife2.com/bld) to build:
+
+```console
+cd readingtime
+./bld compile
+```
+
+The project has an [IntelliJ IDEA](https://www.jetbrains.com/idea/) project structure. You can just open it after all the dependencies were downloaded and peruse the code.
diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml
index 7d98402..ace99d2 100644
--- a/bitbucket-pipelines.yml
+++ b/bitbucket-pipelines.yml
@@ -1,9 +1,20 @@
-image: openjdk:8
+image: ubuntu:latest
pipelines:
default:
- step:
- caches:
- - gradle
+ name: Test with bld
script:
- - bash ./gradlew check
+ # Install latest Java & Kotlin via SDKMAN!
+ - apt-get update -qq && apt-get install -y curl zip
+ - curl -s "https://get.sdkman.io" | bash
+ - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config
+ - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config
+ - source "$HOME/.sdkman/bin/sdkman-init.sh"
+ - sdk install java
+ - sdk install kotlin
+ - source "$HOME/.sdkman/bin/sdkman-init.sh"
+ # Download, compile and test with bld
+ - ./bld download
+ - ./bld compile
+ - ./bld test
diff --git a/bld b/bld
new file mode 100755
index 0000000..7c6b3a7
--- /dev/null
+++ b/bld
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build net.thauvin.erik.ReadingTimeBuild "$@"
\ No newline at end of file
diff --git a/bld.bat b/bld.bat
new file mode 100644
index 0000000..9a33cdf
--- /dev/null
+++ b/bld.bat
@@ -0,0 +1,4 @@
+@echo off
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+java -jar "%DIRNAME%/lib/bld/bld-wrapper.jar" "%0" --build net.thauvin.erik.ReadingTimeBuild %*
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
deleted file mode 100644
index 66abee9..0000000
--- a/build.gradle.kts
+++ /dev/null
@@ -1,188 +0,0 @@
-import org.jetbrains.dokka.gradle.DokkaTask
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import java.io.FileInputStream
-import java.util.*
-
-plugins {
- id("com.github.ben-manes.versions") version "0.38.0"
- id("io.gitlab.arturbosch.detekt") version "1.16.0"
- id("org.jetbrains.dokka") version "1.4.30"
- id("org.jetbrains.kotlin.jvm") version "1.4.30"
- id("org.sonarqube") version "3.1.1"
- `java-library`
- `maven-publish`
- jacoco
- signing
-}
-
-description = "Estimated Reading Time for Blog Posts, Articles, etc."
-group = "net.thauvin.erik"
-version = "0.9.0"
-
-val deployDir = "deploy"
-val gitHub = "ethauvin/$name"
-val mavenUrl = "https://github.com/$gitHub"
-val publicationName = "mavenJava"
-var isRelease = "release" in gradle.startParameter.taskNames
-
-repositories {
- mavenCentral()
- jcenter()
-}
-
-dependencies {
- implementation("org.jsoup:jsoup:1.13.1")
-
- testImplementation("org.jetbrains.kotlin:kotlin-test")
- testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
-}
-
-java {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
- withSourcesJar()
-}
-
-detekt {
- baseline = project.rootDir.resolve("config/detekt/baseline.xml")
-}
-
-sonarqube {
- properties {
- property("sonar.projectKey", "ethauvin_$name")
- property("sonar.sourceEncoding", "UTF-8")
- }
-}
-
-val javadocJar by tasks.creating(Jar::class) {
- dependsOn(tasks.dokkaJavadoc)
- from(tasks.dokkaJavadoc)
- archiveClassifier.set("javadoc")
-}
-
-tasks {
- withType {
- reports {
- xml.isEnabled = true
- html.isEnabled = true
- }
- }
-
- withType().configureEach {
- kotlinOptions.jvmTarget = "1.8"
- }
-
- withType {
- destination = file("$projectDir/pom.xml")
- }
-
- assemble {
- dependsOn(javadocJar)
- }
-
- clean {
- doLast {
- project.delete(fileTree(deployDir))
- }
- }
-
- withType().configureEach {
- dokkaSourceSets {
- named("main") {
- moduleName.set("ReadingTime")
- apiVersion.set("${project.version}")
- }
- }
- }
-
- val copyToDeploy by registering(Copy::class) {
- from(configurations.runtimeClasspath) {
- exclude("annotations-*.jar")
- }
- from(jar)
- into(deployDir)
- }
-
- val gitIsDirty by registering(Exec::class) {
- description = "Fails if git has uncommitted changes."
- group = "verification"
- commandLine("git", "diff", "--quiet", "--exit-code")
- }
-
- val gitTag by registering(Exec::class) {
- description = "Tags the local repository with version ${project.version}"
- group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn(gitIsDirty)
- if (isRelease) {
- commandLine("git", "tag", "-a", project.version, "-m", "Version ${project.version}")
- }
- }
-
- register("deploy") {
- description = "Copies all needed files to the $deployDir directory."
- group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn("build", "jar")
- outputs.dir(deployDir)
- inputs.files(copyToDeploy)
- mustRunAfter("clean")
- }
-
- register("release") {
- description = "Publishes version ${project.version} to local repository."
- group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn("wrapper", "deploy", "gitTag", "publishToMavenLocal")
- }
-
- "sonarqube" {
- dependsOn("jacocoTestReport")
- }
-}
-
-publishing {
- publications {
- create(publicationName) {
- from(components["java"])
- artifact(javadocJar)
- pom {
- name.set(project.name)
- description.set(project.description)
- url.set(mavenUrl)
- licenses {
- license {
- name.set("BSD 3-Clause")
- url.set("https://opensource.org/licenses/BSD-3-Clause")
- }
- }
- developers {
- developer {
- id.set("ethauvin")
- name.set("Erik C. Thauvin")
- email.set("erik@thauvin.net")
- url.set("https://erik.thauvin.net/")
- }
- }
- scm {
- connection.set("scm:git:git://github.com/$gitHub.git")
- developerConnection.set("scm:git:git@github.com:$gitHub.git")
- url.set("$mavenUrl")
- }
- issueManagement {
- system.set("GitHub")
- url.set("$mavenUrl/issues")
- }
- }
- }
- }
- repositories {
- maven {
- name = "ossrh"
- url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
- credentials(PasswordCredentials::class)
- }
- }
-
- signing {
- useGpgCmd()
- sign(publishing.publications[publicationName])
- }
-}
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index 4e17654..fc2da78 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -1,11 +1,13 @@
-
+
+ LongMethod:ReadingTimeTest.kt$ReadingTimeTest$@Test fun testReadingTimeInSec()
+ 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 roundingMode: RoundingMode = RoundingMode.HALF_EVEN )
+ MagicNumber:Config.kt$Config.Builder$275MagicNumber:ReadingTime.kt$ReadingTime$10MagicNumber:ReadingTime.kt$ReadingTime$12MagicNumber:ReadingTime.kt$ReadingTime$3
- MagicNumber:ReadingTime.kt$ReadingTime$60MagicNumber:ReadingTime.kt$ReadingTime$60.0
diff --git a/examples/bld/.gitignore b/examples/bld/.gitignore
new file mode 100644
index 0000000..a2805aa
--- /dev/null
+++ b/examples/bld/.gitignore
@@ -0,0 +1,55 @@
+.gradle
+.DS_Store
+build
+lib/bld/**
+!lib/bld/bld-wrapper.jar
+!lib/bld/bld-wrapper.properties
+lib/compile/
+lib/runtime/
+lib/standalone/
+lib/test/
+
+# IDEA ignores
+
+# User-specific
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Editor-based Rest Client
+.idea/httpRequests
\ No newline at end of file
diff --git a/examples/bld/.idea/.name b/examples/bld/.idea/.name
new file mode 100644
index 0000000..6aeb7d8
--- /dev/null
+++ b/examples/bld/.idea/.name
@@ -0,0 +1 @@
+readingtime-examples-bld
\ No newline at end of file
diff --git a/examples/bld/.idea/app.iml b/examples/bld/.idea/app.iml
new file mode 100644
index 0000000..2c1fe21
--- /dev/null
+++ b/examples/bld/.idea/app.iml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/bld.iml b/examples/bld/.idea/bld.iml
new file mode 100644
index 0000000..e63e11e
--- /dev/null
+++ b/examples/bld/.idea/bld.iml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/inspectionProfiles/Project_Default.xml b/examples/bld/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..1e01b48
--- /dev/null
+++ b/examples/bld/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/libraries/bld.xml b/examples/bld/.idea/libraries/bld.xml
new file mode 100644
index 0000000..af4608e
--- /dev/null
+++ b/examples/bld/.idea/libraries/bld.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/libraries/compile.xml b/examples/bld/.idea/libraries/compile.xml
new file mode 100644
index 0000000..99cc0c0
--- /dev/null
+++ b/examples/bld/.idea/libraries/compile.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/libraries/runtime.xml b/examples/bld/.idea/libraries/runtime.xml
new file mode 100644
index 0000000..d4069f2
--- /dev/null
+++ b/examples/bld/.idea/libraries/runtime.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/libraries/test.xml b/examples/bld/.idea/libraries/test.xml
new file mode 100644
index 0000000..57ed5ef
--- /dev/null
+++ b/examples/bld/.idea/libraries/test.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/misc.xml b/examples/bld/.idea/misc.xml
new file mode 100644
index 0000000..5bfc6ba
--- /dev/null
+++ b/examples/bld/.idea/misc.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/modules.xml b/examples/bld/.idea/modules.xml
new file mode 100644
index 0000000..55adcb9
--- /dev/null
+++ b/examples/bld/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/runConfigurations/Run Tests.xml b/examples/bld/.idea/runConfigurations/Run Tests.xml
new file mode 100644
index 0000000..dd66624
--- /dev/null
+++ b/examples/bld/.idea/runConfigurations/Run Tests.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.idea/vcs.xml b/examples/bld/.idea/vcs.xml
new file mode 100644
index 0000000..b2bdec2
--- /dev/null
+++ b/examples/bld/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/bld/.vscode/launch.json b/examples/bld/.vscode/launch.json
new file mode 100644
index 0000000..ee0090e
--- /dev/null
+++ b/examples/bld/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "java",
+ "name": "Run Tests",
+ "request": "launch",
+ "mainClass": "com.example.ReadingTimeExampleTest"
+ }
+ ]
+}
diff --git a/examples/bld/.vscode/settings.json b/examples/bld/.vscode/settings.json
new file mode 100644
index 0000000..ba429d0
--- /dev/null
+++ b/examples/bld/.vscode/settings.json
@@ -0,0 +1,15 @@
+{
+ "java.project.sourcePaths": [
+ "src/main/java",
+ "src/main/resources",
+ "src/test/java",
+ "src/test/resources",
+ "src/bld/java",
+ "src/bld/resources"
+ ],
+ "java.configuration.updateBuildConfiguration": "automatic",
+ "java.project.referencedLibraries": [
+ "${HOME}/.bld/dist/bld-2.2.1.jar",
+ "lib/**/*.jar"
+ ]
+}
diff --git a/examples/bld/README.md b/examples/bld/README.md
new file mode 100644
index 0000000..13de079
--- /dev/null
+++ b/examples/bld/README.md
@@ -0,0 +1,14 @@
+## Kotlin Example
+To compile & run the Kotlin example:
+
+```console
+./bld compile run --args="example.html"
+```
+
+## Java Example
+
+To compile & run the Java example:
+
+```console
+./bld compile run-java --args="example.html"
+```
diff --git a/examples/bld/bld b/examples/bld/bld
new file mode 100755
index 0000000..0057d8f
--- /dev/null
+++ b/examples/bld/bld
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build com.example.ReadingTimeExampleBuild "$@"
\ No newline at end of file
diff --git a/examples/bld/bld.bat b/examples/bld/bld.bat
new file mode 100644
index 0000000..5b69398
--- /dev/null
+++ b/examples/bld/bld.bat
@@ -0,0 +1,4 @@
+@echo off
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+java -jar "%DIRNAME%/lib/bld/bld-wrapper.jar" "%0" --build com.example.ReadingTimeExampleBuild %*
\ No newline at end of file
diff --git a/examples/example.html b/examples/bld/example.html
similarity index 100%
rename from examples/example.html
rename to examples/bld/example.html
diff --git a/examples/bld/lib/bld/bld-wrapper.jar b/examples/bld/lib/bld/bld-wrapper.jar
new file mode 100644
index 0000000..5313351
Binary files /dev/null and b/examples/bld/lib/bld/bld-wrapper.jar differ
diff --git a/examples/bld/lib/bld/bld-wrapper.properties b/examples/bld/lib/bld/bld-wrapper.properties
new file mode 100644
index 0000000..1f1009d
--- /dev/null
+++ b/examples/bld/lib/bld/bld-wrapper.properties
@@ -0,0 +1,7 @@
+bld.downloadExtensionJavadoc=false
+bld.downloadExtensionSources=true
+bld.downloadLocation=
+bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.1.0-SNAPSHOT
+bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
+bld.sourceDirectories=
+bld.version=2.2.1
diff --git a/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java b/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java
new file mode 100644
index 0000000..279f859
--- /dev/null
+++ b/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java
@@ -0,0 +1,52 @@
+package com.example;
+
+import rife.bld.BuildCommand;
+import rife.bld.extension.CompileKotlinOperation;
+import rife.bld.operations.RunOperation;
+import rife.bld.BaseProject;
+
+import java.util.List;
+
+
+import static rife.bld.dependencies.Repository.*;
+import static rife.bld.dependencies.Scope.compile;
+
+public class ReadingTimeExampleBuild extends BaseProject {
+ public ReadingTimeExampleBuild() {
+ pkg = "com.example";
+ name = "ReadingTimeExample";
+ version = version(0, 1, 0);
+
+ mainClass = "com.example.ReadingTimeExampleKt";
+
+ javaRelease = 11;
+ downloadSources = true;
+ autoDownloadPurge = true;
+ repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, SONATYPE_SNAPSHOTS_LEGACY);
+
+ scope(compile)
+ .include(dependency("net.thauvin.erik", "readingtime", version(0, 9, 3, "SNAPSHOT")));
+ }
+
+ public static void main(String[] args) {
+ new ReadingTimeExampleBuild().start(args);
+ }
+
+ @Override
+ public void compile() throws Exception {
+ new CompileKotlinOperation()
+ .fromProject(this)
+ .execute();
+
+ // Also compile the Java source code
+ super.compile();
+ }
+
+ @BuildCommand(value = "run-java", summary = "Runs the Java example")
+ public void runJava() throws Exception {
+ new RunOperation()
+ .fromProject(this)
+ .mainClass("com.example.ReadingTimeSample")
+ .execute();
+ }
+}
diff --git a/examples/bld/src/main/java/com/example/ReadingTimeSample.java b/examples/bld/src/main/java/com/example/ReadingTimeSample.java
new file mode 100644
index 0000000..5f73ac9
--- /dev/null
+++ b/examples/bld/src/main/java/com/example/ReadingTimeSample.java
@@ -0,0 +1,35 @@
+package com.example;
+
+import net.thauvin.erik.readingtime.ReadingTime;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class ReadingTimeSample {
+ public static void main(String[] args) {
+ if (args.length >= 1) {
+ final Path text = Path.of(args[0]);
+ try {
+ final ReadingTime rt = new ReadingTime(Files.readString(text));
+ rt.setPostfix("minute to read");
+ rt.setPlural("minutes to read");
+
+// final Config config =
+// new Config.Builder(Files.readString(text))
+// .postfix("minute to read")
+// .plural("minutes to read")
+// .build();
+// final ReadingTime rt = new ReadingTime(config);
+
+ System.out.println("It will take " + rt.calcReadingTime() + ' ' + ReadingTime.wordCount(rt.getText())
+ + " words and " + ReadingTime.imgCount(rt.getText()) + " images at " + rt.getWpm()
+ + " words per minute.");
+ } catch (IOException e) {
+ System.err.println("The file could not be read or found.");
+ }
+ } else {
+ System.err.println("Please specify a file as an argument.");
+ }
+ }
+}
diff --git a/examples/src/main/kotlin/com/example/ReadingTimeExample.kt b/examples/bld/src/main/kotlin/com/example/ReadingTimeExample.kt
similarity index 87%
rename from examples/src/main/kotlin/com/example/ReadingTimeExample.kt
rename to examples/bld/src/main/kotlin/com/example/ReadingTimeExample.kt
index e230dbe..8563bc6 100644
--- a/examples/src/main/kotlin/com/example/ReadingTimeExample.kt
+++ b/examples/bld/src/main/kotlin/com/example/ReadingTimeExample.kt
@@ -13,7 +13,7 @@ fun main(args: Array) {
println(
"It will take ${rt.calcReadingTime()} ${ReadingTime.wordCount(rt.text)} words and " +
- "${ReadingTime.imgCount(rt.text)} images at ${rt.wpm} words per minute."
+ "${ReadingTime.imgCount(rt.text)} images at ${rt.wpm} words per minute."
)
} else {
System.err.println("The file could not be read or found.")
diff --git a/examples/src/main/java/com/example/ReadingTimeSample.java b/examples/bld/src/main/main/java/com/example/ReadingTimeSample.java
similarity index 82%
rename from examples/src/main/java/com/example/ReadingTimeSample.java
rename to examples/bld/src/main/main/java/com/example/ReadingTimeSample.java
index 59c469b..faaf6a2 100644
--- a/examples/src/main/java/com/example/ReadingTimeSample.java
+++ b/examples/bld/src/main/main/java/com/example/ReadingTimeSample.java
@@ -16,8 +16,8 @@ public class ReadingTimeSample {
rt.setPlural("minutes to read");
System.out.println("It will take " + rt.calcReadingTime() + ' ' + ReadingTime.wordCount(rt.getText())
- + " words and " + ReadingTime.imgCount(rt.getText()) + " images at " + rt.getWpm()
- + " words per minute.");
+ + " words and " + ReadingTime.imgCount(rt.getText()) + " images at " + rt.getWpm()
+ + " words per minute.");
} catch (IOException e) {
System.err.println("The file could not be read or found.");
}
diff --git a/examples/bld/src/main/main/kotlin/com/example/ReadingTimeExample.kt b/examples/bld/src/main/main/kotlin/com/example/ReadingTimeExample.kt
new file mode 100644
index 0000000..8563bc6
--- /dev/null
+++ b/examples/bld/src/main/main/kotlin/com/example/ReadingTimeExample.kt
@@ -0,0 +1,25 @@
+package com.example
+
+import net.thauvin.erik.readingtime.ReadingTime
+import java.io.File
+
+fun main(args: Array) {
+ if (args.isNotEmpty()) {
+ with(File(args[0])) {
+ if (exists() && canRead()) {
+ val rt = ReadingTime(readText())
+ rt.postfix = "minute to read"
+ rt.plural = "minutes to read"
+
+ println(
+ "It will take ${rt.calcReadingTime()} ${ReadingTime.wordCount(rt.text)} words and " +
+ "${ReadingTime.imgCount(rt.text)} images at ${rt.wpm} words per minute."
+ )
+ } else {
+ System.err.println("The file could not be read or found.")
+ }
+ }
+ } else {
+ System.err.println("Please specify a file as an argument.")
+ }
+}
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
deleted file mode 100644
index ab9c64b..0000000
--- a/examples/build.gradle.kts
+++ /dev/null
@@ -1,34 +0,0 @@
-plugins {
- id("org.jetbrains.kotlin.jvm") version "1.4.31"
- id("com.github.ben-manes.versions") version "0.38.0"
- application
-}
-
-// ./gradlew run --args="example.html"
-// ./gradlew runJava --args="example.html"
-
-repositories {
- mavenLocal()
- mavenCentral()
-}
-
-dependencies {
- implementation("net.thauvin.erik:readingtime:0.9.0")
-}
-
-application {
- mainClassName = "com.example.ReadingTimeExampleKt"
-}
-
-tasks {
- getByName("run") {
- args = listOf("${project.projectDir}/example.html")
- }
-
- register("runJava") {
- group = "application"
- main = "com.example.ReadingTimeSample"
- classpath = sourceSets["main"].runtimeClasspath
- args = listOf("${project.projectDir}/example.html")
- }
-}
diff --git a/examples/.gitattributes b/examples/gradle/.gitattributes
similarity index 100%
rename from examples/.gitattributes
rename to examples/gradle/.gitattributes
diff --git a/examples/.gitignore b/examples/gradle/.gitignore
similarity index 100%
rename from examples/.gitignore
rename to examples/gradle/.gitignore
diff --git a/.idea/.gitignore b/examples/gradle/.idea/.gitignore
similarity index 100%
rename from .idea/.gitignore
rename to examples/gradle/.idea/.gitignore
diff --git a/examples/gradle/.idea/.name b/examples/gradle/.idea/.name
new file mode 100644
index 0000000..9b7d9ec
--- /dev/null
+++ b/examples/gradle/.idea/.name
@@ -0,0 +1 @@
+readingtime-examples-gradle
\ No newline at end of file
diff --git a/.idea/compiler.xml b/examples/gradle/.idea/compiler.xml
similarity index 75%
rename from .idea/compiler.xml
rename to examples/gradle/.idea/compiler.xml
index 61a9130..fb7f4a8 100644
--- a/.idea/compiler.xml
+++ b/examples/gradle/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/gradle.iml b/examples/gradle/.idea/gradle.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/examples/gradle/.idea/gradle.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/gradle.xml b/examples/gradle/.idea/gradle.xml
new file mode 100644
index 0000000..ce1c62c
--- /dev/null
+++ b/examples/gradle/.idea/gradle.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/inspectionProfiles/Project_Default.xml b/examples/gradle/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..1e01b48
--- /dev/null
+++ b/examples/gradle/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/intellij-javadocs-4.0.1.xml b/examples/gradle/.idea/intellij-javadocs-4.0.1.xml
new file mode 100644
index 0000000..5d2c532
--- /dev/null
+++ b/examples/gradle/.idea/intellij-javadocs-4.0.1.xml
@@ -0,0 +1,204 @@
+
+
+
+
+ UPDATE
+ false
+ true
+
+ METHOD
+ FIELD
+ TYPE
+
+
+ DEFAULT
+ PUBLIC
+ PROTECTED
+
+
+
+
+
+ ^.*(public|protected|private)*.+interface\s+\w+.*
+ /**\n
+ * The interface ${name}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+ */
+
+
+ ^.*(public|protected|private)*.+enum\s+\w+.*
+ /**\n
+ * The enum ${name}.\n
+ */
+
+
+ ^.*(public|protected|private)*.+class\s+\w+.*
+ /**\n
+ * The type ${name}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+ */
+
+
+ .+
+ /**\n
+ * The type ${name}.\n
+ */
+
+
+
+
+ .+
+ /**\n
+ * Instantiates a new ${name}.\n
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+
+
+ ^.*(public|protected|private)*\s*.*(\w(\s*<.+>)*)+\s+get\w+\s*\(.*\).+
+ /**\n
+ * Gets ${partName}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${partName}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ ^.*(public|protected|private)*\s*.*(void|\w(\s*<.+>)*)+\s+set\w+\s*\(.*\).+
+ /**\n
+ * Sets ${partName}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${partName}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ ^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+
+ /**\n
+ * The entry point of application.\n
+
+ <#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+ * @param ${element.parameterList.parameters[0].name} the input arguments\n
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ .+
+ /**\n
+ * ${name}<#if isNotVoid> ${return}</#if>.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${return}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+
+
+ ^.*(public|protected|private)*.+static.*(\w\s\w)+.+
+ /**\n
+ * The constant ${element.getName()}.\n
+ */
+
+
+ ^.*(public|protected|private)*.*(\w\s\w)+.+
+ /**\n
+ <#if element.parent.isInterface()>
+ * The constant ${element.getName()}.\n
+<#else>
+ * The ${name}.\n
+</#if> */
+
+
+ .+
+ /**\n
+ <#if element.parent.isEnum()>
+ *${name} ${typeName}.\n
+<#else>
+ * The ${name}.\n
+</#if>*/
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/examples/gradle/.idea/jarRepositories.xml
similarity index 69%
rename from .idea/jarRepositories.xml
rename to examples/gradle/.idea/jarRepositories.xml
index b9c41fe..4e9cedf 100644
--- a/.idea/jarRepositories.xml
+++ b/examples/gradle/.idea/jarRepositories.xml
@@ -11,15 +11,20 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/kotlinc.xml b/examples/gradle/.idea/kotlinc.xml
new file mode 100644
index 0000000..148fdd2
--- /dev/null
+++ b/examples/gradle/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/misc.xml b/examples/gradle/.idea/misc.xml
new file mode 100644
index 0000000..b2ff8cd
--- /dev/null
+++ b/examples/gradle/.idea/misc.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/modules.xml b/examples/gradle/.idea/modules.xml
new file mode 100644
index 0000000..be92c07
--- /dev/null
+++ b/examples/gradle/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/.idea/vcs.xml b/examples/gradle/.idea/vcs.xml
new file mode 100644
index 0000000..b2bdec2
--- /dev/null
+++ b/examples/gradle/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gradle/README.md b/examples/gradle/README.md
new file mode 100644
index 0000000..e0ce033
--- /dev/null
+++ b/examples/gradle/README.md
@@ -0,0 +1,14 @@
+## Kotlin Example
+To compile & run the Kotlin example:
+
+```console
+./gradlew run --args="example.html"
+```
+
+## Java Example
+
+To compile & run the Java example:
+
+```console
+./gradlew runJava --args="example.html"
+```
diff --git a/examples/gradle/build.gradle.kts b/examples/gradle/build.gradle.kts
new file mode 100644
index 0000000..1472671
--- /dev/null
+++ b/examples/gradle/build.gradle.kts
@@ -0,0 +1,38 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+ id("application")
+ id("com.github.ben-manes.versions") version "0.51.0"
+ kotlin("jvm") version "2.1.20"
+}
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+ maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") }
+}
+
+dependencies {
+ implementation("net.thauvin.erik:readingtime:0.9.3-SNAPSHOT")
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+}
+
+application {
+ mainClass.set("com.example.ReadingTimeExampleKt")
+}
+
+kotlin {
+ compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)
+}
+
+tasks {
+ register("runJava") {
+ group = "application"
+ mainClass.set("com.example.ReadingTimeSample")
+ classpath = sourceSets.main.get().runtimeClasspath
+ }
+}
diff --git a/examples/gradle/example.html b/examples/gradle/example.html
new file mode 100644
index 0000000..799fca4
--- /dev/null
+++ b/examples/gradle/example.html
@@ -0,0 +1,127 @@
+
HTML Ipsum Presents
+
+
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
+ Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas
+ semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien
+ ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi.
+ Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.
+
+
+
Definition list
+
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat.
+
Lorem ipsum dolor sit amet
+
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat.
+
+
+
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam,
+ feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies
+ mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat
+ wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros
+ ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.
+ Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam
+ erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus
+
+
Header Level 2
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet
+ congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus
+ est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.
+
+
Header Level 3
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 4
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 5
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+
Aliquam tincidunt mauris eu risus.
+
+
+
+
Header Level 6
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Eons ago, a couple of Medium engineers got fed up. They were sick of having to scroll all the way down the
page to see how long a story was. It was wearing out their trackpad, it was making their fingers sore, and
they figured there must be a better way. So they sat down and devised a simple formula, and the Medium read
@@ -13,48 +13,48 @@
With the widespread
adoption of this feature across the internet, we decided to shed some light on exactly what goes in to
our read time calculation.
-
Read time is based on the
+
Read time is based on the
average reading speed of an adult (roughly 275 WPM). We take the total word count of a post and
translate it into minutes. Then, we add 12 seconds for each inline image. Boom, read
time.
-
Lately, we have
+
Lately, we have
seen more and more long form stories containing a ton of images. With our release of image grids, we expect even more of
+ class="cg dj mm mn mo mp"
+ href="https://medium.com/the-story/introducing-image-grids-c592e5bc16d8" rel="noopener" target="_blank">image grids, we expect even more of
these types of essays.
-
Our original read
+
Our original read
time calculation was geared toward “slow” images, like comics, where you would really want to sit down
and invest in the image. This resulted in articles with crazy big read times. For instance, this article containing 140 images was clocking in at a whopping
+ class="cg dj mm mn mo mp" href="https://medium.com/@dahul/inside-medium-94931f66eebd"
+ rel="noopener" target="_blank">article containing 140 images was clocking in at a whopping
87 minute read. So we amended our read time calculation to count 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 three seconds.
-
You might see this
+
You might see this
change reflected across the site. Keep in mind that our estimated read time is just that: an estimation. You might finish a story faster or slower depending on various
factors such as how many children or cats you have, your caffeine/alcohol intake, or if you’re a
time-traveler from the future and already read that story. We just want to give you a ballpark figure so
you can decide whether you have time to read one more story before the bus comes, or if you should
bookmark it for later.
-
We aren’t done with
+
We aren’t done with
read time yet. In the future, we’d like to tailor it to your reading speed, account for the complexity of an article, and add
+ class="cg dj mm mn mo mp"
+ href="https://medium.com/@fchimero/this-should-only-take-a-minute-or-four-probably-e38bb7bf2adf" rel="noopener" target="_blank">complexity of an article, and add
support for other languages. We’ll be sure to let you know about these changes as they happen.
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
- commodo consequat.
+ commodo consequat.
+
Lorem ipsum dolor sit amet
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
- commodo consequat.
+ commodo consequat.
+
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam,