Compare commits

...

96 commits

Author SHA1 Message Date
e6c9b5de23
Add snapshot repository 2025-03-26 13:12:22 -07:00
45a095e4aa
Add OS matrix for Ubuntu, Windows and macOS 2025-03-26 13:07:01 -07:00
a6b2d50fca
Add extension logging 2025-03-26 13:06:32 -07:00
4f9baf3d8c
Update to latest snapshots 2025-03-26 13:06:20 -07:00
061727151b
Combine Kotlin compile options 2025-03-20 10:56:58 -07:00
24e6da2305
Add Kotlin compile options for JDK 24 2025-03-20 09:52:52 -07:00
21b9f8bf70
Bump Kotlin to version 2.1.20 2025-03-20 09:52:11 -07:00
8e0f7e9eae
JDK 24 2025-03-18 23:57:33 -07:00
6f2ff8dc4b
Update Java/Kotlin matrices to current versions 2025-03-16 18:30:47 -07:00
7274d4fa39
Update license copyright 2025-03-16 12:55:57 -07:00
7f4e2a8421
Update root pom 2025-03-16 12:12:18 -07:00
ad879b36e4
Update copyright 2025-03-16 12:12:05 -07:00
f4f831895d
Add parameters kdoc for builder constructor 2025-03-16 12:09:27 -07:00
918efe4c70
Updated extensions dependencies
Bump Detekt extension to version 0.9.9
Bump Dokka extension to version 1.0.3
Bump Jacoco Report extension to version 0.9.9
2025-03-16 12:09:26 -07:00
45d1d402bb
Bump Kotlin extension to version 1.0.4 2025-03-16 12:06:43 -07:00
c0e0989863
Bump Java matrix from version 22 to 23 2025-03-16 12:06:11 -07:00
dba879dcbc
Bump Kotlin to version 2.1.10 2025-03-16 12:05:34 -07:00
05361c981e
Bump JSoup to version 1.19.1 2025-03-16 12:04:22 -07:00
dbc782aca8
Bump JUnit to version 5.12.1 2025-03-16 12:03:52 -07:00
a5dbf0b546
Bump Gradle to version 8.13 2025-03-16 12:03:24 -07:00
4d78c7f86d
Bump bld to version 2.2.1 2025-03-16 12:02:32 -07:00
c3341994f3
Updated dependencies
Bumped bld to version 2.1.0
Bumped Gradle to version 8.10.1
Bumped Kotlin to version 2.0.20
Bumped JUnit to version 5.11.0
2024-09-20 23:12:10 -07:00
378427bfef
Made config constructor private 2024-05-26 00:33:45 -07:00
414fbc07cb
Cleaned up config. 2024-05-25 22:15:39 -07:00
bfb7ebcc09
Bumped Kotlin to version 2.0.0 2024-05-25 21:58:19 -07:00
1d9bafb6a9
Bumped Kotlin extension to version 0.9.5 2024-05-19 04:09:41 -07:00
9d71b7a598
Added return types to builder functions. 2024-05-19 02:13:01 -07:00
9088716047
Builder configuration initialization requires text. 2024-05-17 02:05:09 -07:00
258b8126bb
Minor cleanups 2024-05-12 12:08:27 -07:00
8d4f608e90
Updated copyright 2024-05-11 23:23:45 -07:00
962aa6a86c
Added Config builder 2024-05-11 16:35:09 -07:00
281f43fe1d
Bumped Gradle to version 8.7 2024-05-10 11:49:18 -07:00
e2d3713d28
Bumped JaCoCo extension to version 0.9.5 2024-05-10 11:47:20 -07:00
8893b9f3b0
Bumped Kotlin to version 1.9.24 2024-05-10 11:45:40 -07:00
96d691e8ad
Bumped bld to version 1.9.1 2024-05-10 11:42:20 -07:00
16c2ad05a9
Bumped workflow actions to latest versions 2024-05-10 11:40:28 -07:00
4f1d915e69 Bumped bld to 1.9.0 2024-02-26 17:46:18 -08:00
dbdb6d26f7 Bumped depedencies 2024-01-31 18:00:52 -08:00
8a40f0ab80 Added contributing section 2024-01-31 18:00:05 -08:00
55d3cffeb1 Bump bld to 1.8.0 2024-01-31 17:59:37 -08:00
1718499497 Fixed maven-central label color 2023-11-26 04:27:25 -08:00
0d863f7b65 Version 0.9.2 2023-11-26 04:19:12 -08:00
f1c5f1030c Added detekt extension 2023-11-25 21:16:56 -08:00
32e68cd079 Upgraded to Kotlin 1.9.21 2023-11-23 17:51:52 -08:00
265c852f14 Minor cleanup 2023-11-12 16:09:07 -08:00
c2a13b4ca6 Added sonatype identification 2023-11-08 19:01:16 -08:00
60f5c6ea43 Fixed snapshot badge link 2023-11-08 19:00:54 -08:00
c7770bce42 Added snapshot to example
Added Kotlin badge
2023-11-08 18:51:16 -08:00
e1ea7b0252 Minor cleanup 2023-11-08 16:56:31 -08:00
31cb262752 Added project name and version to Javadoc 2023-11-08 14:37:09 -08:00
f2dd70afb7 Removed caches from some pipelines 2023-11-08 13:46:45 -08:00
66d30f1e31 Added maven cache to Bitbucket pipeline 2023-11-08 13:23:30 -08:00
78bbe6592b Reworkd Bitbucket pipeline 2023-11-08 13:13:41 -08:00
5b0d56926d Minore cleanup 2023-11-08 12:57:58 -08:00
b9d1de5f4c Cleanup pipelines 2023-11-08 12:51:35 -08:00
c25646e265 Switched GitLab and BitBucket pipelines to single stage 2023-11-08 12:42:26 -08:00
3e834ae310 Changed some pipelines to OpenJDK 2023-11-08 12:29:36 -08:00
b26a7e50ad Removed JDK 11 from pipelines 2023-11-08 12:17:28 -08:00
e99fad47c7 Moved from Gradle to bld 2023-11-08 12:10:45 -08:00
22c5d30ace Fixed Kover xml report location 2023-06-29 12:06:10 -07:00
b88bb8cdc2 Fixed Kover reports 2023-06-29 11:52:46 -07:00
46dbe3d201 Updated dependencies 2023-06-29 11:38:22 -07:00
4821274d13 Cleaned up tests 2022-10-04 12:46:45 -07:00
96fbbd6634 Upgraded to Kotlin 1.7.20 2022-09-30 22:31:47 -07:00
290ec8d116 Version 0.9.1 2022-08-25 16:44:51 -07:00
c5bd4d4748 Fixed sonarqube/kover report location 2022-08-25 14:59:57 -07:00
fba34f80ce Merge branch '0.9.1-dev' 2022-08-25 14:14:31 -07:00
4f3cedadd3 Updated dependencies and copyright 2022-08-25 14:06:32 -07:00
9f0146a971 Updated dependencies 2022-04-28 21:53:15 -07:00
266817ed89 Updated dependencies and copyright. 2022-01-03 12:06:14 -08:00
f09b3e9610 Upgraded jsoup to 1.14.3 2021-10-01 22:58:19 -07:00
79689f4932 Upgraded to Kotlin 1.5.31 and JDK 17. 2021-10-01 22:55:54 -07:00
0a0469c5e0 Updated to Kotlin 1.5.30. 2021-08-24 22:20:01 -07:00
233b1acdb2 Upgraded to Kotlin 1.5.21 and JDK 16. 2021-07-27 09:10:04 -07:00
a345330421 Updated dependencies. 2021-07-11 19:22:21 -07:00
eb14e72255 Upgraded to Gradle 7.1. 2021-06-20 01:34:19 -07:00
4c4f7da0da Cleanup. 2021-06-11 20:07:35 -07:00
4bf4a7ec09 Added Github workflow martix for JDK 1.8, 11 & 15. 2021-05-31 11:55:18 -07:00
022950b8d4 Added matrix for Java 11 & 15. 2021-05-31 01:04:23 -07:00
76113a3526 Changed rounding default mode to HALF_EVEN. 2021-05-30 21:17:21 -07:00
644429b1ad Renamed round parameter to roundingMode. 2021-05-30 20:48:21 -07:00
6cabd2e723 Added round parameter. Closes #1 2021-05-30 18:08:57 -07:00
d99218f43b Improved KDocs. 2021-05-27 01:43:00 -07:00
6c8cc7806e Cleanup. 2021-05-27 01:25:26 -07:00
f17ce191d7 Using system wide Gradle. 2021-05-21 13:06:27 -07:00
6d340eb5c4 Removed TravisCI. 2021-05-20 20:05:42 -07:00
b81d486f34 Fixed long lines. 2021-05-19 22:09:32 -07:00
547d235ecb Moved Sonarqube to GitHub action. 2021-05-19 21:54:21 -07:00
f575b67436 Fix for Gitlab CI 2021-05-11 21:50:51 -07:00
b55e3a6956 Upgraded to Gradle 7.0.1 2021-05-11 20:42:28 -07:00
b1810846a5 Added support for snapshot. 2021-05-02 20:51:19 -07:00
2c48f94e6d Using Jacoco snapshot. 2021-04-28 20:03:36 -07:00
bfecf857a2 Upgraded to Kotlin 1.5.0 2021-04-28 12:48:54 -07:00
317c39dfb5 Cleanup 2021-04-28 12:43:42 -07:00
39a9e934a0 Removed repository from example. 2021-03-20 17:20:51 -07:00
821e4f84c4 Updated Maven Central badge. 2021-03-20 16:54:20 -07:00
103 changed files with 2469 additions and 1114 deletions

View file

@ -1,54 +1,62 @@
version: 2
version: 2.1
orbs:
sdkman: joshdholtz/sdkman@0.2.0
defaults: &defaults
working_directory: ~/repo
environment:
JVM_OPTS: -Xmx3200m
TERM: dumb
CI: true
CI_NAME: "CircleCI"
defaults_gradle: &defaults_gradle
steps:
- checkout
- restore_cache:
keys:
- gradle-dependencies-{{ checksum "build.gradle.kts" }}
# fallback to using the latest cache if no exact match is found
- gradle-dependencies-
- run:
name: Gradle Dependencies
command: ./gradlew dependencies
- save_cache:
paths: ~/.m2
key: gradle-dependencies-{{ checksum "build.gradle.kts" }}
- run:
name: Run All Checks
command: ./gradlew check
- store_artifacts:
path: build/reports/
destination: reports
- store_test_results:
path: build/reports/
commands:
build_and_test:
parameters:
reports-dir:
type: string
default: "build/reports/test_results"
steps:
- checkout
- sdkman/setup-sdkman
- sdkman/sdkman-install:
candidate: kotlin
version: 2.1.10
- run:
name: Download dependencies
command: ./bld download
- run:
name: Compile source
command: ./bld compile
- run:
name: Run tests
command: ./bld jacoco -reports-dir=<< parameters.reports-dir >>
- store_test_results:
path: << parameters.reports-dir >>
- store_artifacts:
path: build/reports/jacoco/test/html
jobs:
build_gradle_jdk14:
bld_jdk17:
<<: *defaults
docker:
- image: openjdk:14-jdk
- image: cimg/openjdk:17.0
<<: *defaults_gradle
steps:
- build_and_test
build_gradle_jdk8:
bld_jdk21:
<<: *defaults
docker:
- image: circleci/openjdk:8-jdk
- image: cimg/openjdk:21.0
<<: *defaults_gradle
steps:
- build_and_test
workflows:
version: 2
gradle:
bld:
jobs:
- build_gradle_jdk8
- build_gradle_jdk14
- bld_jdk17
- bld_jdk21

69
.github/workflows/bld.yml vendored Normal file
View file

@ -0,0 +1,69 @@
name: bld-ci
on: [ push, pull_request, workflow_dispatch ]
env:
COVERAGE_JDK: "21"
COVERAGE_KOTLIN: "2.1.20"
jobs:
build-bld-project:
strategy:
matrix:
java-version: [ 17, 21, 24 ]
kotlin-version: [ 1.9.25, 2.0.21, 2.1.20 ]
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout source repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK ${{ matrix.java-version }} with Kotlin ${{ matrix.kotlin-version }}
uses: actions/setup-java@v4
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
- name: Download dependencies [bld example]
working-directory: examples/bld
run: ./bld download
- name: Compile and run [bld examples]
working-directory: examples/bld
run: |
./bld compile
./bld run --args="example.html"
./bld run-java --args="example.html"
- name: Run example [gradle examples]
working-directory: examples/gradle
if: matrix.java-version != '24'
run: |
./gradlew run --args="example.html"
./gradlew run --args="example.html"
- name: Download dependencies
run: ./bld download
- name: Compile source
run: ./bld compile
- name: Run tests
run: ./bld jacoco
- name: Remove pom.xml
if: success() && matrix.java-version == env.COVERAGE_JDK && matrix.kotlin-version == env.COVERAGE_KOTLIN
&& matrix.os == 'ubuntu-latest'
run: rm -rf pom.xml
- name: SonarCloud Scan
uses: sonarsource/sonarcloud-github-action@master
if: success() && matrix.java-version == env.COVERAGE_JDK && matrix.kotlin-version == env.COVERAGE_KOTLIN
&& matrix.os == 'ubuntu-latest'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

View file

@ -1,18 +0,0 @@
name: Java CI with Gradle
on: [push, pull_request, workflow_dispatch]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Test with Gradle
run: ./gradlew check

135
.gitignore vendored
View file

@ -1,84 +1,57 @@
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/settings.json
!.vscode/tasks.json
*.class
*.code-workspace
*.ctxt
*.iws
*.log
*.nar
*.rar
*.sublime-*
*.tar.gz
*.zip
.DS_Store
.classpath
.gradle
.history
.kobalt
.mtj.tmp/
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.nb-gradle
.project
.scannerwork
.settings
.vscode/*
/**/.idea/$CACHE_FILE$
/**/.idea/$PRODUCT_WORKSPACE_FILE$
/**/.idea/**/caches/build_file_checksums.ser
/**/.idea/**/contentModel.xml
/**/.idea/**/dataSources.ids
/**/.idea/**/dataSources.local.xml
/**/.idea/**/dataSources/
/**/.idea/**/dbnavigator.xml
/**/.idea/**/dictionaries
/**/.idea/**/dynamic.xml
/**/.idea/**/gradle.xml
/**/.idea/**/httpRequests
/**/.idea/**/libraries
/**/.idea/**/mongoSettings.xml
/**/.idea/**/replstate.xml
/**/.idea/**/shelf
/**/.idea/**/shelf/
/**/.idea/**/sqlDataSources.xml
/**/.idea/**/tasks.xml
/**/.idea/**/uiDesigner.xml
/**/.idea/**/usage.statistics.xml
/**/.idea/**/workspace.xml
/**/.idea_modules/
Thumbs.db
__pycache__
.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
bin/
build/
cmake-build-*/
com_crashlytics_export_strings.xml
crashlytics-build.properties
crashlytics.properties
dependency-reduced-pom.xml
deploy/
dist/
ehthumbs.db
fabric.properties
gen/
gradle.properties
hs_err_pid*
kobaltBuild
kobaltw*-test
lib/kotlin*
libs/
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Editor-based Rest Client
.idea/httpRequests
local.properties
out/
pom.xml.asc
pom.xml.next
pom.xml.releaseBackup
pom.xml.tag
pom.xml.versionsBackup
proguard-project.txt
project.properties
release.properties
target/
test-output
venv

View file

@ -1,31 +1,24 @@
image: gradle:alpine
image: fedora:latest
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
CI_NAME: "GitLab CI"
stages:
- build
- test
build:
stage: build
script: ./gradlew --build-cache assemble
cache:
key: "$CI_COMMIT_REF_NAME"
policy: push
paths:
- build
- .gradle
before_script:
- dnf -qy update && dnf -y install 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"
test:
stage: test
script: ./gradlew check
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- build
- .gradle
script:
- ./bld download
- ./bld compile
- ./bld test

1
.idea/.name generated
View file

@ -1 +0,0 @@
readingtime

28
.idea/app.iml generated Normal file
View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/main" />
<output-test url="file://$MODULE_DIR$/build/test" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" relativeOutputPath="resources" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="RUNTIME">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/src/main/resources/templates" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="compile" level="project" />
<orderEntry type="library" scope="RUNTIME" name="runtime" level="project" />
<orderEntry type="library" scope="TEST" name="test" level="project" />
</component>
</module>

14
.idea/bld.iml generated Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/bld" />
<output-test url="file://$MODULE_DIR$/build/bld" />
<exclude-output />
<content url="file://$MODULE_DIR$/src/bld">
<sourceFolder url="file://$MODULE_DIR$/src/bld/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="bld" level="project" />
</component>
</module>

6
.idea/bld.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BldConfiguration">
<events />
</component>
</project>

6
.idea/copyright/BSD_3.xml generated Normal file
View file

@ -0,0 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) 2020-&amp;#36;today.year, Erik C. Thauvin (erik@thauvin.net)&#10;All rights reserved.&#10;&#10;Redistribution and use in source and binary forms, with or without&#10;modification, are permitted provided that the following conditions are met:&#10;&#10; Redistributions of source code must retain the above copyright notice, this&#10; list of conditions and the following disclaimer.&#10;&#10; Redistributions in binary form must reproduce the above copyright notice,&#10; this list of conditions and the following disclaimer in the documentation&#10; and/or other materials provided with the distribution.&#10;&#10; Neither the name of this project nor the names of its contributors may be&#10; used to endorse or promote products derived from this software without&#10; specific prior written permission.&#10;&#10;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;&#10;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&#10;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE&#10;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE&#10;FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL&#10;DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR&#10;SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER&#10;CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,&#10;OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE&#10;OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." />
<option name="myName" value="BSD-3" />
</copyright>
</component>

View file

@ -1,6 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="&amp;#36;file.fileName&#10;&#10;Copyright (c) &amp;#36;today.year, Erik C. Thauvin (erik@thauvin.net)&#10;All rights reserved.&#10;&#10;Redistribution and use in source and binary forms, with or without&#10;modification, are permitted provided that the following conditions are met:&#10;&#10; Redistributions of source code must retain the above copyright notice, this&#10; list of conditions and the following disclaimer.&#10;&#10; Redistributions in binary form must reproduce the above copyright notice,&#10; this list of conditions and the following disclaimer in the documentation&#10; and/or other materials provided with the distribution.&#10;&#10; Neither the name of this project nor the names of its contributors may be&#10; used to endorse or promote products derived from this software without&#10; specific prior written permission.&#10;&#10;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;&#10;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&#10;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE&#10;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE&#10;FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL&#10;DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR&#10;SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER&#10;CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,&#10;OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE&#10;OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." />
<option name="myName" value="Erik's Copyright Notice" />
</copyright>
</component>

View file

@ -1,3 +1,3 @@
<component name="CopyrightManager">
<settings default="Erik's Copyright Notice" />
<settings default="BSD-3" />
</component>

View file

@ -1,36 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="created" />
<inspection_tool class="JavadocDeclaration" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ADDITIONAL_TAGS" value="created" />
</inspection_tool>
</profile>
</component>

204
.idea/intellij-javadocs-4.0.1.xml generated Normal file
View file

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaDocConfiguration">
<GENERAL>
<MODE>UPDATE</MODE>
<OVERRIDDEN_METHODS>false</OVERRIDDEN_METHODS>
<SPLITTED_CLASS_NAME>true</SPLITTED_CLASS_NAME>
<LEVELS>
<LEVEL>METHOD</LEVEL>
<LEVEL>TYPE</LEVEL>
<LEVEL>FIELD</LEVEL>
</LEVELS>
<VISIBILITIES>
<VISIBILITY>DEFAULT</VISIBILITY>
<VISIBILITY>PUBLIC</VISIBILITY>
<VISIBILITY>PROTECTED</VISIBILITY>
</VISIBILITIES>
</GENERAL>
<TEMPLATES>
<CLASSES>
<CLASS>
<KEY>^.*(public|protected|private)*.+interface\s+\w+.*</KEY>
<VALUE>/**\n
* The interface ${name}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
*/</VALUE>
</CLASS>
<CLASS>
<KEY>^.*(public|protected|private)*.+enum\s+\w+.*</KEY>
<VALUE>/**\n
* The enum ${name}.\n
*/</VALUE>
</CLASS>
<CLASS>
<KEY>^.*(public|protected|private)*.+class\s+\w+.*</KEY>
<VALUE>/**\n
* The type ${name}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
*/</VALUE>
</CLASS>
<CLASS>
<KEY>.+</KEY>
<VALUE>/**\n
* The type ${name}.\n
*/</VALUE>
</CLASS>
</CLASSES>
<CONSTRUCTORS>
<CONSTRUCTOR>
<KEY>.+</KEY>
<VALUE>/**\n
* Instantiates a new ${name}.\n
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</CONSTRUCTOR>
</CONSTRUCTORS>
<METHODS>
<METHOD>
<KEY>^.*(public|protected|private)*\s*.*(\w(\s*&lt;.+&gt;)*)+\s+get\w+\s*\(.*\).+</KEY>
<VALUE>/**\n
* Gets ${partName}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${partName}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>^.*(public|protected|private)*\s*.*(void|\w(\s*&lt;.+&gt;)*)+\s+set\w+\s*\(.*\).+</KEY>
<VALUE>/**\n
* Sets ${partName}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${partName}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+</KEY>
<VALUE>/**\n
* The entry point of application.\n
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
* @param ${element.parameterList.parameters[0].name} the input arguments\n
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>.+</KEY>
<VALUE>/**\n
* ${name}&lt;#if isNotVoid&gt; ${return}&lt;/#if&gt;.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${return}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
</METHODS>
<FIELDS>
<FIELD>
<KEY>^.*(public|protected|private)*.+static.*(\w\s\w)+.+</KEY>
<VALUE>/**\n
* The constant ${element.getName()}.\n
*/</VALUE>
</FIELD>
<FIELD>
<KEY>^.*(public|protected|private)*.*(\w\s\w)+.+</KEY>
<VALUE>/**\n
&lt;#if element.parent.isInterface()&gt;
* The constant ${element.getName()}.\n
&lt;#else&gt;
* The ${name}.\n
&lt;/#if&gt; */</VALUE>
</FIELD>
<FIELD>
<KEY>.+</KEY>
<VALUE>/**\n
&lt;#if element.parent.isEnum()&gt;
*${name} ${typeName}.\n
&lt;#else&gt;
* The ${name}.\n
&lt;/#if&gt;*/</VALUE>
</FIELD>
</FIELDS>
</TEMPLATES>
</component>
</project>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinScriptingSettings">
<option name="suppressDefinitionsCheck" value="true" />
</component>
</project>

18
.idea/libraries/bld.xml generated Normal file
View file

@ -0,0 +1,18 @@
<component name="libraryTable">
<library name="bld">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES>
<excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
</excluded>
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" type="SOURCES" />
</library>
</component>

13
.idea/libraries/compile.xml generated Normal file
View file

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="compile">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library>
</component>

14
.idea/libraries/runtime.xml generated Normal file
View file

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
<root url="file://$PROJECT_DIR$/src/main/resources" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library>
</component>

14
.idea/libraries/test.xml generated Normal file
View file

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="test">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/test" />
<root url="file://$PROJECT_DIR$/src/test/resources" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library>
</component>

31
.idea/misc.xml generated
View file

@ -1,5 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_14" default="false" project-jdk-name="14" project-jdk-type="JavaSDK" />
<component name="EntryPointsManager">
<pattern value="net.thauvin.erik.ReadingTimeBuild" method="jacoco" />
<pattern value="net.thauvin.erik.ReadingTimeBuild" />
<pattern value="net.thauvin.erik.ReadingTimeBuild" method="detekt" />
<pattern value="net.thauvin.erik.ReadingTimeBuild" method="detektBaseline" />
</component>
<component name="PDMPlugin">
<option name="customRuleSets">
<list>
<option value="K:\java\semver\config\pmd.xml" />
<option value="$PROJECT_DIR$/../../java/bld-pitest/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/rife2/bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/rife2/bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/rife2/bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/rife2/bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/rife2/bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../java/rife2/bld-pitest/config/pmd.xml" />
</list>
</option>
<option name="skipTestSources" value="false" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build" />
</component>
</project>

9
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/app.iml" filepath="$PROJECT_DIR$/.idea/app.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/bld.iml" filepath="$PROJECT_DIR$/.idea/bld.iml" />
</modules>
</component>
</project>

9
.idea/runConfigurations/Run Tests.xml generated Normal file
View file

@ -0,0 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Tests" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="net.thauvin.erik.ReadingTimeTest" />
<module name="app" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

2
.idea/vcs.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

View file

@ -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

11
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Run Tests",
"request": "launch",
"mainClass": "net.thauvin.erik.ReadingTimeTest"
}
]
}

15
.vscode/settings.json vendored Normal file
View file

@ -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"
]
}

View file

@ -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

116
README.md
View file

@ -1,10 +1,18 @@
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause) [![Release](https://img.shields.io/github/release/ethauvin/readingtime.svg)](https://github.com/ethauvin/readingtime/releases/latest) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/readingtime/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/readingtime)
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause)
[![Kotlin](https://img.shields.io/badge/kotlin-2.1.20-7f52ff)](https://kotlinlang.org/)
[![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld)
[![Release](https://img.shields.io/github/release/ethauvin/readingtime.svg)](https://github.com/ethauvin/readingtime/releases/latest)
[![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik/readingtime.svg?color=blue)](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22readingtime%22)
[![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik/readingtime?label=snapshot&server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/readingtime/)
[![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/readingtime/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/ethauvin/readingtime?targetFile=pom.xml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_readingtime&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_readingtime) [![Build Status](https://travis-ci.com/ethauvin/readingtime.svg?branch=master)](https://travis-ci.com/ethauvin/readingtime) [![CircleCI](https://circleci.com/gh/ethauvin/readingtime/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/readingtime/tree/master)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_readingtime&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_readingtime)
[![GitHub CI](https://github.com/ethauvin/readingtime/actions/workflows/bld.yml/badge.svg)](https://github.com/ethauvin/readingtime/actions/workflows/bld.yml)
[![CircleCI](https://circleci.com/gh/ethauvin/readingtime/tree/master.svg?style=shield)](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.

View file

@ -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

2
bld Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build net.thauvin.erik.ReadingTimeBuild "$@"

4
bld.bat Normal file
View file

@ -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 %*

View file

@ -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<JacocoReport> {
reports {
xml.isEnabled = true
html.isEnabled = true
}
}
withType<KotlinCompile>().configureEach {
kotlinOptions.jvmTarget = "1.8"
}
withType<GenerateMavenPom> {
destination = file("$projectDir/pom.xml")
}
assemble {
dependsOn(javadocJar)
}
clean {
doLast {
project.delete(fileTree(deployDir))
}
}
withType<DokkaTask>().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<MavenPublication>(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])
}
}

View file

@ -1,11 +1,13 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<ManuallySuppressedIssues></ManuallySuppressedIssues>
<CurrentIssues>
<ID>LongMethod:ReadingTimeTest.kt$ReadingTimeTest$@Test fun testReadingTimeInSec()</ID>
<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 roundingMode: RoundingMode = RoundingMode.HALF_EVEN )</ID>
<ID>MagicNumber:Config.kt$Config.Builder$275</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>

55
examples/bld/.gitignore vendored Normal file
View file

@ -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

1
examples/bld/.idea/.name generated Normal file
View file

@ -0,0 +1 @@
readingtime-examples-bld

30
examples/bld/.idea/app.iml generated Normal file
View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/main" />
<output-test url="file://$MODULE_DIR$/build/test" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" relativeOutputPath="resources" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="RUNTIME">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/src/main/resources/templates" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="compile" level="project" />
<orderEntry type="library" scope="RUNTIME" name="runtime" level="project" />
<orderEntry type="library" scope="TEST" name="test" level="project" />
</component>
</module>

14
examples/bld/.idea/bld.iml generated Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/bld" />
<output-test url="file://$MODULE_DIR$/build/bld" />
<exclude-output />
<content url="file://$MODULE_DIR$/src/bld">
<sourceFolder url="file://$MODULE_DIR$/src/bld/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="bld" level="project" />
</component>
</module>

View file

@ -0,0 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavadocDeclaration" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ADDITIONAL_TAGS" value="created" />
</inspection_tool>
</profile>
</component>

17
examples/bld/.idea/libraries/bld.xml generated Normal file
View file

@ -0,0 +1,17 @@
<component name="libraryTable">
<library name="bld">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES>
<excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
</excluded>
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" type="SOURCES" />
</library>
</component>

13
examples/bld/.idea/libraries/compile.xml generated Normal file
View file

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="compile">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library>
</component>

14
examples/bld/.idea/libraries/runtime.xml generated Normal file
View file

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
<root url="file://$PROJECT_DIR$/src/main/resources" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library>
</component>

14
examples/bld/.idea/libraries/test.xml generated Normal file
View file

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="test">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/test" />
<root url="file://$PROJECT_DIR$/src/test/resources" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library>
</component>

30
examples/bld/.idea/misc.xml generated Normal file
View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<pattern value="com.example.ReadingTimeExampleBuild" />
<pattern value="com.example.ReadingTimeExampleBuild" method="runJava" />
</component>
<component name="PDMPlugin">
<option name="customRuleSets">
<list>
<option value="K:\java\semver\config\pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-pitest/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-pitest/config/pmd.xml" />
</list>
</option>
<option name="skipTestSources" value="false" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build" />
</component>
</project>

9
examples/bld/.idea/modules.xml generated Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/app.iml" filepath="$PROJECT_DIR$/.idea/app.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/bld.iml" filepath="$PROJECT_DIR$/.idea/bld.iml" />
</modules>
</component>
</project>

View file

@ -0,0 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Tests" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.example.ReadingTimeExampleTest" />
<module name="app" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

6
examples/bld/.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

11
examples/bld/.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Run Tests",
"request": "launch",
"mainClass": "com.example.ReadingTimeExampleTest"
}
]
}

15
examples/bld/.vscode/settings.json vendored Normal file
View file

@ -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"
]
}

14
examples/bld/README.md Normal file
View file

@ -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"
```

2
examples/bld/bld Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build com.example.ReadingTimeExampleBuild "$@"

4
examples/bld/bld.bat Normal file
View file

@ -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 %*

Binary file not shown.

View file

@ -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

View file

@ -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();
}
}

View file

@ -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.");
}
}
}

View file

@ -13,7 +13,7 @@ fun main(args: Array<String>) {
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.")

View file

@ -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.");
}

View file

@ -0,0 +1,25 @@
package com.example
import net.thauvin.erik.readingtime.ReadingTime
import java.io.File
fun main(args: Array<String>) {
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.")
}
}

View file

@ -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<JavaExec>("run") {
args = listOf("${project.projectDir}/example.html")
}
register<JavaExec>("runJava") {
group = "application"
main = "com.example.ReadingTimeSample"
classpath = sourceSets["main"].runtimeClasspath
args = listOf("${project.projectDir}/example.html")
}
}

1
examples/gradle/.idea/.name generated Normal file
View file

@ -0,0 +1 @@
readingtime-examples-gradle

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
<bytecodeTargetLevel target="11" />
</component>
</project>

9
examples/gradle/.idea/gradle.iml generated Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

16
examples/gradle/.idea/gradle.xml generated Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View file

@ -0,0 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavadocDeclaration" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ADDITIONAL_TAGS" value="created" />
</inspection_tool>
</profile>
</component>

View file

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaDocConfiguration">
<GENERAL>
<MODE>UPDATE</MODE>
<OVERRIDDEN_METHODS>false</OVERRIDDEN_METHODS>
<SPLITTED_CLASS_NAME>true</SPLITTED_CLASS_NAME>
<LEVELS>
<LEVEL>METHOD</LEVEL>
<LEVEL>FIELD</LEVEL>
<LEVEL>TYPE</LEVEL>
</LEVELS>
<VISIBILITIES>
<VISIBILITY>DEFAULT</VISIBILITY>
<VISIBILITY>PUBLIC</VISIBILITY>
<VISIBILITY>PROTECTED</VISIBILITY>
</VISIBILITIES>
</GENERAL>
<TEMPLATES>
<CLASSES>
<CLASS>
<KEY>^.*(public|protected|private)*.+interface\s+\w+.*</KEY>
<VALUE>/**\n
* The interface ${name}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
*/</VALUE>
</CLASS>
<CLASS>
<KEY>^.*(public|protected|private)*.+enum\s+\w+.*</KEY>
<VALUE>/**\n
* The enum ${name}.\n
*/</VALUE>
</CLASS>
<CLASS>
<KEY>^.*(public|protected|private)*.+class\s+\w+.*</KEY>
<VALUE>/**\n
* The type ${name}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
*/</VALUE>
</CLASS>
<CLASS>
<KEY>.+</KEY>
<VALUE>/**\n
* The type ${name}.\n
*/</VALUE>
</CLASS>
</CLASSES>
<CONSTRUCTORS>
<CONSTRUCTOR>
<KEY>.+</KEY>
<VALUE>/**\n
* Instantiates a new ${name}.\n
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</CONSTRUCTOR>
</CONSTRUCTORS>
<METHODS>
<METHOD>
<KEY>^.*(public|protected|private)*\s*.*(\w(\s*&lt;.+&gt;)*)+\s+get\w+\s*\(.*\).+</KEY>
<VALUE>/**\n
* Gets ${partName}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${partName}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>^.*(public|protected|private)*\s*.*(void|\w(\s*&lt;.+&gt;)*)+\s+set\w+\s*\(.*\).+</KEY>
<VALUE>/**\n
* Sets ${partName}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${partName}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+</KEY>
<VALUE>/**\n
* The entry point of application.\n
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
* @param ${element.parameterList.parameters[0].name} the input arguments\n
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>.+</KEY>
<VALUE>/**\n
* ${name}&lt;#if isNotVoid&gt; ${return}&lt;/#if&gt;.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${return}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
</METHODS>
<FIELDS>
<FIELD>
<KEY>^.*(public|protected|private)*.+static.*(\w\s\w)+.+</KEY>
<VALUE>/**\n
* The constant ${element.getName()}.\n
*/</VALUE>
</FIELD>
<FIELD>
<KEY>^.*(public|protected|private)*.*(\w\s\w)+.+</KEY>
<VALUE>/**\n
&lt;#if element.parent.isInterface()&gt;
* The constant ${element.getName()}.\n
&lt;#else&gt;
* The ${name}.\n
&lt;/#if&gt; */</VALUE>
</FIELD>
<FIELD>
<KEY>.+</KEY>
<VALUE>/**\n
&lt;#if element.parent.isEnum()&gt;
*${name} ${typeName}.\n
&lt;#else&gt;
* The ${name}.\n
&lt;/#if&gt;*/</VALUE>
</FIELD>
</FIELDS>
</TEMPLATES>
</component>
</project>

View file

@ -11,15 +11,20 @@
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
</remote-repository>
</component>
</project>

6
examples/gradle/.idea/kotlinc.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.24" />
</component>
</project>

28
examples/gradle/.idea/misc.xml generated Normal file
View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="PDMPlugin">
<option name="customRuleSets">
<list>
<option value="K:\java\semver\config\pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-pitest/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../../../../java/rife2/bld-pitest/config/pmd.xml" />
</list>
</option>
<option name="skipTestSources" value="false" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

8
examples/gradle/.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/gradle.iml" filepath="$PROJECT_DIR$/.idea/gradle.iml" />
</modules>
</component>
</project>

6
examples/gradle/.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

14
examples/gradle/README.md Normal file
View file

@ -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"
```

View file

@ -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<JavaExec>("runJava") {
group = "application"
mainClass.set("com.example.ReadingTimeSample")
classpath = sourceSets.main.get().runtimeClasspath
}
}

View file

@ -0,0 +1,127 @@
<h1>HTML Ipsum Presents</h1>
<p><strong>Pellentesque habitant morbi tristique</strong> 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. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien
ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi.
Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a
href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
<dl>
<dt>Definition list</dt>
<dd>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.</dd>
<dt>Lorem ipsum dolor sit amet</dt>
<dd>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.</dd>
</dl>
<p>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</p>
<h2>Header Level 2</h2>
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ol>
<blockquote><p>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.</p></blockquote>
<h3>Header Level 3</h3>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h4>Header Level 4</h4>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h5>Header Level 5</h5>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<h6>Header Level 6</h6>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li><img src="#"></li>
</ul>
<pre><code>
#header h1 a {
display: block;
width: 300px;
height: 80px;
}
</code></pre>

Binary file not shown.

View file

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

251
examples/gradle/gradlew vendored Executable file
View file

@ -0,0 +1,251 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View file

@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View file

@ -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.");
}
}
}

View file

@ -0,0 +1,25 @@
package com.example
import net.thauvin.erik.readingtime.ReadingTime
import java.io.File
fun main(args: Array<String>) {
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.")
}
}

Binary file not shown.

185
examples/gradlew vendored
View file

@ -1,185 +0,0 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

Binary file not shown.

View file

@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored
View file

@ -1,185 +0,0 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored
View file

@ -1,89 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

BIN
lib/bld/bld-wrapper.jar Normal file

Binary file not shown.

View file

@ -0,0 +1,10 @@
bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.downloadLocation=
bld.extension-detekt=com.uwyn.rife2:bld-detekt:0.9.10-SNAPSHOT
bld.extension-dokka=com.uwyn.rife2:bld-dokka:1.0.4-SNAPSHOT
bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.10-SNAPSHOT
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

44
pom.xml
View file

@ -1,14 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>net.thauvin.erik</groupId>
<artifactId>readingtime</artifactId>
<version>0.9.0</version>
<version>0.9.3-SNAPSHOT</version>
<name>readingtime</name>
<description>Estimated Reading Time for Blog Posts, Articles, etc.</description>
<url>https://github.com/ethauvin/readingtime</url>
@ -18,6 +14,20 @@
<url>https://opensource.org/licenses/BSD-3-Clause</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>2.1.20</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.19.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<developers>
<developer>
<id>ethauvin</id>
@ -27,26 +37,8 @@
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/ethauvin/readingtime.git</connection>
<connection>scm:git:https://github.com/ethauvin/readingtime.git</connection>
<developerConnection>scm:git:git@github.com:ethauvin/readingtime.git</developerConnection>
<url>https://github.com/ethauvin/readingtime</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/ethauvin/readingtime/issues</url>
</issueManagement>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.4.30</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,10 +0,0 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.5.1/userguide/multi_project_builds.html
*/
rootProject.name = "readingtime"

7
sonar-project.properties Normal file
View file

@ -0,0 +1,7 @@
sonar.organization=ethauvin-github
sonar.projectKey=ethauvin_readingtime
sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml
sonar.sources=src/main/kotlin/
sonar.tests=src/test/kotlin/
sonar.java.binaries=build/main,build/test
sonar.java.libraries=lib/compile/*.jar

View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 2020-2025, Erik C. Thauvin (erik@thauvin.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.thauvin.erik;
import rife.bld.BuildCommand;
import rife.bld.Project;
import rife.bld.extension.CompileKotlinOperation;
import rife.bld.extension.DetektOperation;
import rife.bld.extension.DokkaOperation;
import rife.bld.extension.JacocoReportOperation;
import rife.bld.extension.dokka.LoggingLevel;
import rife.bld.extension.dokka.OutputFormat;
import rife.bld.extension.kotlin.CompileOptions;
import rife.bld.operations.exceptions.ExitStatusException;
import rife.bld.publish.PomBuilder;
import rife.bld.publish.PublishDeveloper;
import rife.bld.publish.PublishLicense;
import rife.bld.publish.PublishScm;
import rife.tools.exceptions.FileUtilsErrorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import static rife.bld.dependencies.Repository.*;
import static rife.bld.dependencies.Scope.compile;
import static rife.bld.dependencies.Scope.test;
public class ReadingTimeBuild extends Project {
private static final String DETEKT_BASELINE = "config/detekt/baseline.xml";
private final File srcMainKotlin = new File(srcMainDirectory(), "kotlin");
public ReadingTimeBuild() {
pkg = "net.thauvin.erik";
name = "readingtime";
version = version(0, 9, 3, "SNAPSHOT");
javaRelease = 11;
downloadSources = true;
autoDownloadPurge = true;
repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL);
final var kotlin = version(2, 1, 20);
scope(compile)
.include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin))
.include(dependency("org.jsoup", "jsoup", version(1, 19, 1)));
scope(test)
.include(dependency("org.jetbrains.kotlin", "kotlin-test-junit5", kotlin))
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 1)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 1)))
.include(dependency("org.junit.platform", "junit-platform-launcher", version(1, 12, 1)));
publishOperation()
.repository(version.isSnapshot() ? repository(SONATYPE_SNAPSHOTS_LEGACY.location())
.withCredentials(property("sonatype.user"), property("sonatype.password"))
: repository(SONATYPE_RELEASES_LEGACY.location())
.withCredentials(property("sonatype.user"), property("sonatype.password")))
.repository(repository("github"))
.info()
.groupId(pkg)
.artifactId(name)
.description("Estimated Reading Time for Blog Posts, Articles, etc.")
.url("https://github.com/ethauvin/" + name)
.developer(new PublishDeveloper()
.id("ethauvin")
.name("Erik C. Thauvin")
.email("erik@thauvin.net")
.url("https://erik.thauvin.net/")
)
.license(new PublishLicense()
.name("BSD 3-Clause")
.url("https://opensource.org/licenses/BSD-3-Clause")
)
.scm(new PublishScm()
.connection("scm:git:https://github.com/ethauvin/" + name + ".git")
.developerConnection("scm:git:git@github.com:ethauvin/" + name + ".git")
.url("https://github.com/ethauvin/" + name)
)
.signKey(property("sign.key"))
.signPassphrase(property("sign.passphrase"));
jarSourcesOperation().sourceDirectories(srcMainKotlin);
}
public static void main(String[] args) {
// Enable detailed logging for the extensions
var level = Level.ALL;
var logger = Logger.getLogger("rife.bld.extension");
var consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(level);
logger.addHandler(consoleHandler);
logger.setLevel(level);
logger.setUseParentHandlers(false);
new ReadingTimeBuild().start(args);
}
@BuildCommand(summary = "Compiles the Kotlin project")
@Override
public void compile() throws Exception {
new CompileKotlinOperation()
.fromProject(this)
.compileOptions(new CompileOptions().verbose(true))
.execute();
}
@BuildCommand(summary = "Checks source with Detekt")
public void detekt() throws ExitStatusException, IOException, InterruptedException {
new DetektOperation()
.fromProject(this)
.baseline(DETEKT_BASELINE)
.execute();
}
@BuildCommand(value = "detekt-baseline", summary = "Creates the Detekt baseline")
public void detektBaseline() throws ExitStatusException, IOException, InterruptedException {
new DetektOperation()
.fromProject(this)
.baseline(DETEKT_BASELINE)
.createBaseline(true)
.execute();
}
@BuildCommand(summary = "Generates JaCoCo Reports")
public void jacoco() throws Exception {
new JacocoReportOperation()
.fromProject(this)
.sourceFiles(srcMainKotlin)
.execute();
}
@Override
public void javadoc() throws ExitStatusException, IOException, InterruptedException {
new DokkaOperation()
.fromProject(this)
.loggingLevel(LoggingLevel.INFO)
.moduleName("ReadingTime")
.moduleVersion(version.toString())
.outputDir(new File(buildDirectory(), "javadoc"))
.outputFormat(OutputFormat.JAVADOC)
.execute();
}
@Override
public void publish() throws Exception {
super.publish();
pomRoot();
}
@Override
public void publishLocal() throws Exception {
super.publishLocal();
pomRoot();
}
@BuildCommand(value = "pom-root", summary = "Generates the POM file in the root directory")
public void pomRoot() throws FileUtilsErrorException {
PomBuilder.generateInto(publishOperation().fromProject(this).info(), dependencies(),
new File(workDirectory, "pom.xml"));
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2020-2025, Erik C. Thauvin (erik@thauvin.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.thauvin.erik.readingtime
import java.math.RoundingMode
/**
* Configuration class for reading time calculations.
*
* @property text The text to be evaluated.
* @property wpm The words per minute reading average.
* @property postfix The text to append after the reading time.
* @property plural The text to append after the reading time if plural.
* @property excludeImages Whether to exclude images in the word count.
* @property extra Additional time to add to the reading time.
* @property roundingMode The rounding mode to apply to the reading time.
*/
class Config private constructor(builder: Builder) {
val text = builder.text
val wpm = builder.wpm
val postfix = builder.postfix
val plural = builder.plural
val excludeImages = builder.excludeImages
val extra = builder.extra
val roundingMode = builder.roundingMode
/**
* Configures the parameters.
*
* @param text The text to be evaluated.
*/
data class Builder(var text: String) {
var wpm: Int = 275
var postfix: String = "min read"
var plural: String = "min read"
var excludeImages: Boolean = false
var extra: Int = 0
var roundingMode: RoundingMode = RoundingMode.HALF_EVEN
/**
* The text to be evaluated.
*/
fun text(text: String): Builder = apply { this.text = text }
/**
* The words per minute reading average.
*/
fun wpm(wpm: Int): Builder = apply { this.wpm = wpm }
/**
* The value to be appended to the reading time.
*/
fun postfix(postfix: String): Builder = apply { this.postfix = postfix }
/**
* The value to be appended if the reading time is more than 1 minute.
*/
fun plural(plural: String): Builder = apply { this.plural = plural }
/**
* Images are excluded from the reading time when set.
*/
fun excludeImages(excludeImages: Boolean): Builder = apply { this.excludeImages = excludeImages }
/**
* Additional seconds to be added to the total reading time.
*/
fun extra(extra: Int): Builder = apply { this.extra = extra }
/**
* The [RoundingMode] to apply. Default is [RoundingMode.HALF_DOWN].
*/
fun roundingMode(roundingMode: RoundingMode): Builder = apply { this.roundingMode = roundingMode }
/**
* Builds the configuration.
*/
fun build(): Config = Config(this)
}
}

View file

@ -1,7 +1,5 @@
/*
* ReadingTime.kt
*
* 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
@ -41,12 +39,15 @@ import java.math.RoundingMode
*
* Based on [Medium's calculation](https://blog.medium.com/read-time-and-you-bc2048ab620c).
*
* @constructor Constructs a new [ReadingTime] object.
*
* @param text The text to be evaluated.
* @param wpm 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 excludeImages Images are excluded from the reading time when set.
* @param extra Additional seconds to be added to the total reading time.
* @param roundingMode The [RoundingMode] to apply. Default is [RoundingMode.HALF_DOWN].
*/
class ReadingTime @JvmOverloads constructor(
text: String,
@ -54,8 +55,19 @@ class ReadingTime @JvmOverloads constructor(
var postfix: String = "min read",
var plural: String = "min read",
excludeImages: Boolean = false,
extra: Int = 0
) {
extra: Int = 0,
var roundingMode: RoundingMode = RoundingMode.HALF_EVEN
) {
constructor(config: Config) : this(
config.text,
config.wpm,
config.postfix,
config.plural,
config.excludeImages,
config.extra,
config.roundingMode
)
companion object {
private const val INVALID: Double = -1.0
@ -107,6 +119,8 @@ class ReadingTime @JvmOverloads constructor(
/**
* Calculates and returns the reading time in seconds.
*
* `((word count / wpm) * 60) + images + extra`
*/
fun calcReadingTimeInSec(): Double {
if (readTime == INVALID) {
@ -118,10 +132,12 @@ class ReadingTime @JvmOverloads constructor(
}
/**
* Calculates and returns the reading time. (eg. 1 min read)
* Calculates and returns the reading time. (e.g. 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, roundingMode)
return if (time.compareTo(BigDecimal.ONE) == 1) {
"$time $plural".trim()
} else {
@ -129,6 +145,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)

View file

@ -1,7 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0"
<!--
~ Copyright (c) 2020-2025, Erik C. Thauvin (erik@thauvin.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.
-->
<taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>ReadingTime</short-name>

View file

@ -1,23 +1,46 @@
<%--
Copyright (c) 2020-2021, Erik C. Thauvin (erik@thauvin.net)
All rights reserved.
See: https://erik.thauvin.net/licenses/bsd.shtml
--%>
<%@tag body-content="scriptless" import="net.thauvin.erik.readingtime.ReadingTime" trimDirectiveWhitespaces="true"%>
<%@attribute name="debug" type="java.lang.Boolean"%>
<%@attribute name="excludeImages" type="java.lang.Boolean"%>
<%@attribute name="extra" type="java.lang.Integer"%>
<%@attribute name="plural"%>
<%@attribute name="postfix"%>
<%@attribute name="wpm" type="java.lang.Integer"%>
~ Copyright (c) 2020-2025, Erik C. Thauvin (erik@thauvin.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.
--%>
<%@tag body-content="scriptless" import="net.thauvin.erik.readingtime.ReadingTime" trimDirectiveWhitespaces="true" %>
<%@attribute name="debug" type="java.lang.Boolean" %>
<%@attribute name="excludeImages" type="java.lang.Boolean" %>
<%@attribute name="extra" type="java.lang.Integer" %>
<%@attribute name="plural" %>
<%@attribute name="postfix" %>
<%@attribute name="wpm" type="java.lang.Integer" %>
<jsp:doBody var="body" scope="page"/>
<%
final Boolean debug = (Boolean) getJspContext().getAttribute("debug");
final Boolean excludeImages = (Boolean) getJspContext().getAttribute("excludeImages");
final Integer extra = (Integer) getJspContext().getAttribute("extra");
final Integer wpm = (Integer) getJspContext().getAttribute("wpm");
final String body = (String) getJspContext().getAttribute("body");;
final String body = (String) getJspContext().getAttribute("body");
final String plural = (String) getJspContext().getAttribute("plural");
final String postfix = (String) getJspContext().getAttribute("postfix");

Some files were not shown because too many files have changed in this diff Show more