diff --git a/.circleci/config.yml b/.circleci/config.yml index cc73045..c781fdc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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 diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml new file mode 100644 index 0000000..cb652d4 --- /dev/null +++ b/.github/workflows/bld.yml @@ -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 }} diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml deleted file mode 100644 index d9750d9..0000000 --- a/.github/workflows/gradle.yml +++ /dev/null @@ -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 diff --git a/.gitignore b/.gitignore index a602396..ea86fe8 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 26820aa..10b9b0f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 9aa979d..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -readingtime \ No newline at end of file diff --git a/.idea/app.iml b/.idea/app.iml new file mode 100644 index 0000000..b074dbd --- /dev/null +++ b/.idea/app.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/bld.iml b/.idea/bld.iml new file mode 100644 index 0000000..e63e11e --- /dev/null +++ b/.idea/bld.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/bld.xml b/.idea/bld.xml new file mode 100644 index 0000000..6600cee --- /dev/null +++ b/.idea/bld.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/copyright/BSD_3.xml b/.idea/copyright/BSD_3.xml new file mode 100644 index 0000000..16075c3 --- /dev/null +++ b/.idea/copyright/BSD_3.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/Erik_s_Copyright_Notice.xml b/.idea/copyright/Erik_s_Copyright_Notice.xml deleted file mode 100644 index 08660a1..0000000 --- a/.idea/copyright/Erik_s_Copyright_Notice.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index 1419e40..3203074 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 838047c..1e01b48 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,36 +1,8 @@ \ No newline at end of file diff --git a/.idea/intellij-javadocs-4.0.1.xml b/.idea/intellij-javadocs-4.0.1.xml new file mode 100644 index 0000000..3ed9781 --- /dev/null +++ b/.idea/intellij-javadocs-4.0.1.xml @@ -0,0 +1,204 @@ + + + + + UPDATE + false + true + + METHOD + TYPE + FIELD + + + DEFAULT + PUBLIC + PROTECTED + + + + + + ^.*(public|protected|private)*.+interface\s+\w+.* + /**\n + * The interface ${name}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> + */ + + + ^.*(public|protected|private)*.+enum\s+\w+.* + /**\n + * The enum ${name}.\n + */ + + + ^.*(public|protected|private)*.+class\s+\w+.* + /**\n + * The type ${name}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> + */ + + + .+ + /**\n + * The type ${name}.\n + */ + + + + + .+ + /**\n + * Instantiates a new ${name}.\n +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + + + ^.*(public|protected|private)*\s*.*(\w(\s*<.+>)*)+\s+get\w+\s*\(.*\).+ + /**\n + * Gets ${partName}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if isNotVoid> + *\n + * @return the ${partName}\n +</#if> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + ^.*(public|protected|private)*\s*.*(void|\w(\s*<.+>)*)+\s+set\w+\s*\(.*\).+ + /**\n + * Sets ${partName}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if isNotVoid> + *\n + * @return the ${partName}\n +</#if> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + ^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+ + /**\n + * The entry point of application.\n + + <#if element.parameterList.parameters?has_content> + *\n +</#if> + * @param ${element.parameterList.parameters[0].name} the input arguments\n +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + .+ + /**\n + * ${name}<#if isNotVoid> ${return}</#if>.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if isNotVoid> + *\n + * @return the ${return}\n +</#if> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + + + ^.*(public|protected|private)*.+static.*(\w\s\w)+.+ + /**\n + * The constant ${element.getName()}.\n + */ + + + ^.*(public|protected|private)*.*(\w\s\w)+.+ + /**\n + <#if element.parent.isInterface()> + * The constant ${element.getName()}.\n +<#else> + * The ${name}.\n +</#if> */ + + + .+ + /**\n + <#if element.parent.isEnum()> + *${name} ${typeName}.\n +<#else> + * The ${name}.\n +</#if>*/ + + + + + \ No newline at end of file diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml deleted file mode 100644 index bc444de..0000000 --- a/.idea/kotlinScripting.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml new file mode 100644 index 0000000..153a060 --- /dev/null +++ b/.idea/libraries/bld.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/.idea/libraries/compile.xml b/.idea/libraries/compile.xml new file mode 100644 index 0000000..99cc0c0 --- /dev/null +++ b/.idea/libraries/compile.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/runtime.xml b/.idea/libraries/runtime.xml new file mode 100644 index 0000000..d4069f2 --- /dev/null +++ b/.idea/libraries/runtime.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/test.xml b/.idea/libraries/test.xml new file mode 100644 index 0000000..57ed5ef --- /dev/null +++ b/.idea/libraries/test.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index fe5a948..96b0faa 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,32 @@ - - + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..55adcb9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Run Tests.xml b/.idea/runConfigurations/Run Tests.xml new file mode 100644 index 0000000..068d7e9 --- /dev/null +++ b/.idea/runConfigurations/Run Tests.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c709d84..0000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: java -dist: trusty - -env: - global: - - CI=true - -#install: -# - git fetch --unshallow --tags - -addons: - sonarcloud: - organization: "ethauvin-github" - -jdk: - - oraclejdk8 - - openjdk15 - -before_install: - - chmod +x gradlew - -after_success: - - | - if [ "${TRAVIS_TEST_RESULT}" == 0 ] && [ "$TRAVIS_JDK_VERSION" == "openjdk15" ]; then - ./gradlew sonarqube - fi diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ae95f51 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Run Tests", + "request": "launch", + "mainClass": "net.thauvin.erik.ReadingTimeTest" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ba429d0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "java.project.sourcePaths": [ + "src/main/java", + "src/main/resources", + "src/test/java", + "src/test/resources", + "src/bld/java", + "src/bld/resources" + ], + "java.configuration.updateBuildConfiguration": "automatic", + "java.project.referencedLibraries": [ + "${HOME}/.bld/dist/bld-2.2.1.jar", + "lib/**/*.jar" + ] +} diff --git a/LICENSE.TXT b/LICENSE.TXT index 15551d4..8af7d8e 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,4 +1,4 @@ -Copyright (c) 2020-2021, Erik C. Thauvin (erik@thauvin.net) +Copyright (c) 2020-2025, Erik C. Thauvin (erik@thauvin.net) All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index f13afd8..7a41220 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,18 @@ -[![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. diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 7d98402..ace99d2 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -1,9 +1,20 @@ -image: openjdk:8 +image: ubuntu:latest pipelines: default: - step: - caches: - - gradle + name: Test with bld script: - - bash ./gradlew check + # Install latest Java & Kotlin via SDKMAN! + - apt-get update -qq && apt-get install -y curl zip + - curl -s "https://get.sdkman.io" | bash + - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config + - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config + - source "$HOME/.sdkman/bin/sdkman-init.sh" + - sdk install java + - sdk install kotlin + - source "$HOME/.sdkman/bin/sdkman-init.sh" + # Download, compile and test with bld + - ./bld download + - ./bld compile + - ./bld test diff --git a/bld b/bld new file mode 100755 index 0000000..7c6b3a7 --- /dev/null +++ b/bld @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build net.thauvin.erik.ReadingTimeBuild "$@" \ No newline at end of file diff --git a/bld.bat b/bld.bat new file mode 100644 index 0000000..9a33cdf --- /dev/null +++ b/bld.bat @@ -0,0 +1,4 @@ +@echo off +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +java -jar "%DIRNAME%/lib/bld/bld-wrapper.jar" "%0" --build net.thauvin.erik.ReadingTimeBuild %* \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts deleted file mode 100644 index 66abee9..0000000 --- a/build.gradle.kts +++ /dev/null @@ -1,188 +0,0 @@ -import org.jetbrains.dokka.gradle.DokkaTask -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import java.io.FileInputStream -import java.util.* - -plugins { - id("com.github.ben-manes.versions") version "0.38.0" - id("io.gitlab.arturbosch.detekt") version "1.16.0" - id("org.jetbrains.dokka") version "1.4.30" - id("org.jetbrains.kotlin.jvm") version "1.4.30" - id("org.sonarqube") version "3.1.1" - `java-library` - `maven-publish` - jacoco - signing -} - -description = "Estimated Reading Time for Blog Posts, Articles, etc." -group = "net.thauvin.erik" -version = "0.9.0" - -val deployDir = "deploy" -val gitHub = "ethauvin/$name" -val mavenUrl = "https://github.com/$gitHub" -val publicationName = "mavenJava" -var isRelease = "release" in gradle.startParameter.taskNames - -repositories { - mavenCentral() - jcenter() -} - -dependencies { - implementation("org.jsoup:jsoup:1.13.1") - - testImplementation("org.jetbrains.kotlin:kotlin-test") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit") -} - -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - withSourcesJar() -} - -detekt { - baseline = project.rootDir.resolve("config/detekt/baseline.xml") -} - -sonarqube { - properties { - property("sonar.projectKey", "ethauvin_$name") - property("sonar.sourceEncoding", "UTF-8") - } -} - -val javadocJar by tasks.creating(Jar::class) { - dependsOn(tasks.dokkaJavadoc) - from(tasks.dokkaJavadoc) - archiveClassifier.set("javadoc") -} - -tasks { - withType { - reports { - xml.isEnabled = true - html.isEnabled = true - } - } - - withType().configureEach { - kotlinOptions.jvmTarget = "1.8" - } - - withType { - destination = file("$projectDir/pom.xml") - } - - assemble { - dependsOn(javadocJar) - } - - clean { - doLast { - project.delete(fileTree(deployDir)) - } - } - - withType().configureEach { - dokkaSourceSets { - named("main") { - moduleName.set("ReadingTime") - apiVersion.set("${project.version}") - } - } - } - - val copyToDeploy by registering(Copy::class) { - from(configurations.runtimeClasspath) { - exclude("annotations-*.jar") - } - from(jar) - into(deployDir) - } - - val gitIsDirty by registering(Exec::class) { - description = "Fails if git has uncommitted changes." - group = "verification" - commandLine("git", "diff", "--quiet", "--exit-code") - } - - val gitTag by registering(Exec::class) { - description = "Tags the local repository with version ${project.version}" - group = PublishingPlugin.PUBLISH_TASK_GROUP - dependsOn(gitIsDirty) - if (isRelease) { - commandLine("git", "tag", "-a", project.version, "-m", "Version ${project.version}") - } - } - - register("deploy") { - description = "Copies all needed files to the $deployDir directory." - group = PublishingPlugin.PUBLISH_TASK_GROUP - dependsOn("build", "jar") - outputs.dir(deployDir) - inputs.files(copyToDeploy) - mustRunAfter("clean") - } - - register("release") { - description = "Publishes version ${project.version} to local repository." - group = PublishingPlugin.PUBLISH_TASK_GROUP - dependsOn("wrapper", "deploy", "gitTag", "publishToMavenLocal") - } - - "sonarqube" { - dependsOn("jacocoTestReport") - } -} - -publishing { - publications { - create(publicationName) { - from(components["java"]) - artifact(javadocJar) - pom { - name.set(project.name) - description.set(project.description) - url.set(mavenUrl) - licenses { - license { - name.set("BSD 3-Clause") - url.set("https://opensource.org/licenses/BSD-3-Clause") - } - } - developers { - developer { - id.set("ethauvin") - name.set("Erik C. Thauvin") - email.set("erik@thauvin.net") - url.set("https://erik.thauvin.net/") - } - } - scm { - connection.set("scm:git:git://github.com/$gitHub.git") - developerConnection.set("scm:git:git@github.com:$gitHub.git") - url.set("$mavenUrl") - } - issueManagement { - system.set("GitHub") - url.set("$mavenUrl/issues") - } - } - } - } - repositories { - maven { - name = "ossrh" - url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") - credentials(PasswordCredentials::class) - } - } - - signing { - useGpgCmd() - sign(publishing.publications[publicationName]) - } -} diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index 4e17654..fc2da78 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -1,11 +1,13 @@ - + + LongMethod:ReadingTimeTest.kt$ReadingTimeTest$@Test fun testReadingTimeInSec() + LongParameterList:ReadingTime.kt$ReadingTime$( text: String, wpm: Int = 275, var postfix: String = "min read", var plural: String = "min read", excludeImages: Boolean = false, extra: Int = 0, var roundingMode: RoundingMode = RoundingMode.HALF_EVEN ) + MagicNumber:Config.kt$Config.Builder$275 MagicNumber:ReadingTime.kt$ReadingTime$10 MagicNumber:ReadingTime.kt$ReadingTime$12 MagicNumber:ReadingTime.kt$ReadingTime$3 - MagicNumber:ReadingTime.kt$ReadingTime$60 MagicNumber:ReadingTime.kt$ReadingTime$60.0 diff --git a/examples/bld/.gitignore b/examples/bld/.gitignore new file mode 100644 index 0000000..a2805aa --- /dev/null +++ b/examples/bld/.gitignore @@ -0,0 +1,55 @@ +.gradle +.DS_Store +build +lib/bld/** +!lib/bld/bld-wrapper.jar +!lib/bld/bld-wrapper.properties +lib/compile/ +lib/runtime/ +lib/standalone/ +lib/test/ + +# IDEA ignores + +# User-specific +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Editor-based Rest Client +.idea/httpRequests \ No newline at end of file diff --git a/examples/bld/.idea/.name b/examples/bld/.idea/.name new file mode 100644 index 0000000..6aeb7d8 --- /dev/null +++ b/examples/bld/.idea/.name @@ -0,0 +1 @@ +readingtime-examples-bld \ No newline at end of file diff --git a/examples/bld/.idea/app.iml b/examples/bld/.idea/app.iml new file mode 100644 index 0000000..2c1fe21 --- /dev/null +++ b/examples/bld/.idea/app.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/bld.iml b/examples/bld/.idea/bld.iml new file mode 100644 index 0000000..e63e11e --- /dev/null +++ b/examples/bld/.idea/bld.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/inspectionProfiles/Project_Default.xml b/examples/bld/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1e01b48 --- /dev/null +++ b/examples/bld/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/examples/bld/.idea/libraries/bld.xml b/examples/bld/.idea/libraries/bld.xml new file mode 100644 index 0000000..af4608e --- /dev/null +++ b/examples/bld/.idea/libraries/bld.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/libraries/compile.xml b/examples/bld/.idea/libraries/compile.xml new file mode 100644 index 0000000..99cc0c0 --- /dev/null +++ b/examples/bld/.idea/libraries/compile.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/libraries/runtime.xml b/examples/bld/.idea/libraries/runtime.xml new file mode 100644 index 0000000..d4069f2 --- /dev/null +++ b/examples/bld/.idea/libraries/runtime.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/libraries/test.xml b/examples/bld/.idea/libraries/test.xml new file mode 100644 index 0000000..57ed5ef --- /dev/null +++ b/examples/bld/.idea/libraries/test.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/misc.xml b/examples/bld/.idea/misc.xml new file mode 100644 index 0000000..5bfc6ba --- /dev/null +++ b/examples/bld/.idea/misc.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/modules.xml b/examples/bld/.idea/modules.xml new file mode 100644 index 0000000..55adcb9 --- /dev/null +++ b/examples/bld/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/examples/bld/.idea/runConfigurations/Run Tests.xml b/examples/bld/.idea/runConfigurations/Run Tests.xml new file mode 100644 index 0000000..dd66624 --- /dev/null +++ b/examples/bld/.idea/runConfigurations/Run Tests.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/examples/bld/.idea/vcs.xml b/examples/bld/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/examples/bld/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/bld/.vscode/launch.json b/examples/bld/.vscode/launch.json new file mode 100644 index 0000000..ee0090e --- /dev/null +++ b/examples/bld/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Run Tests", + "request": "launch", + "mainClass": "com.example.ReadingTimeExampleTest" + } + ] +} diff --git a/examples/bld/.vscode/settings.json b/examples/bld/.vscode/settings.json new file mode 100644 index 0000000..ba429d0 --- /dev/null +++ b/examples/bld/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "java.project.sourcePaths": [ + "src/main/java", + "src/main/resources", + "src/test/java", + "src/test/resources", + "src/bld/java", + "src/bld/resources" + ], + "java.configuration.updateBuildConfiguration": "automatic", + "java.project.referencedLibraries": [ + "${HOME}/.bld/dist/bld-2.2.1.jar", + "lib/**/*.jar" + ] +} diff --git a/examples/bld/README.md b/examples/bld/README.md new file mode 100644 index 0000000..13de079 --- /dev/null +++ b/examples/bld/README.md @@ -0,0 +1,14 @@ +## Kotlin Example +To compile & run the Kotlin example: + +```console +./bld compile run --args="example.html" +``` + +## Java Example + +To compile & run the Java example: + +```console +./bld compile run-java --args="example.html" +``` diff --git a/examples/bld/bld b/examples/bld/bld new file mode 100755 index 0000000..0057d8f --- /dev/null +++ b/examples/bld/bld @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build com.example.ReadingTimeExampleBuild "$@" \ No newline at end of file diff --git a/examples/bld/bld.bat b/examples/bld/bld.bat new file mode 100644 index 0000000..5b69398 --- /dev/null +++ b/examples/bld/bld.bat @@ -0,0 +1,4 @@ +@echo off +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +java -jar "%DIRNAME%/lib/bld/bld-wrapper.jar" "%0" --build com.example.ReadingTimeExampleBuild %* \ No newline at end of file diff --git a/examples/example.html b/examples/bld/example.html similarity index 100% rename from examples/example.html rename to examples/bld/example.html diff --git a/examples/bld/lib/bld/bld-wrapper.jar b/examples/bld/lib/bld/bld-wrapper.jar new file mode 100644 index 0000000..5313351 Binary files /dev/null and b/examples/bld/lib/bld/bld-wrapper.jar differ diff --git a/examples/bld/lib/bld/bld-wrapper.properties b/examples/bld/lib/bld/bld-wrapper.properties new file mode 100644 index 0000000..1f1009d --- /dev/null +++ b/examples/bld/lib/bld/bld-wrapper.properties @@ -0,0 +1,7 @@ +bld.downloadExtensionJavadoc=false +bld.downloadExtensionSources=true +bld.downloadLocation= +bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.1.0-SNAPSHOT +bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES +bld.sourceDirectories= +bld.version=2.2.1 diff --git a/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java b/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java new file mode 100644 index 0000000..279f859 --- /dev/null +++ b/examples/bld/src/bld/java/com/example/ReadingTimeExampleBuild.java @@ -0,0 +1,52 @@ +package com.example; + +import rife.bld.BuildCommand; +import rife.bld.extension.CompileKotlinOperation; +import rife.bld.operations.RunOperation; +import rife.bld.BaseProject; + +import java.util.List; + + +import static rife.bld.dependencies.Repository.*; +import static rife.bld.dependencies.Scope.compile; + +public class ReadingTimeExampleBuild extends BaseProject { + public ReadingTimeExampleBuild() { + pkg = "com.example"; + name = "ReadingTimeExample"; + version = version(0, 1, 0); + + mainClass = "com.example.ReadingTimeExampleKt"; + + javaRelease = 11; + downloadSources = true; + autoDownloadPurge = true; + repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, SONATYPE_SNAPSHOTS_LEGACY); + + scope(compile) + .include(dependency("net.thauvin.erik", "readingtime", version(0, 9, 3, "SNAPSHOT"))); + } + + public static void main(String[] args) { + new ReadingTimeExampleBuild().start(args); + } + + @Override + public void compile() throws Exception { + new CompileKotlinOperation() + .fromProject(this) + .execute(); + + // Also compile the Java source code + super.compile(); + } + + @BuildCommand(value = "run-java", summary = "Runs the Java example") + public void runJava() throws Exception { + new RunOperation() + .fromProject(this) + .mainClass("com.example.ReadingTimeSample") + .execute(); + } +} diff --git a/examples/bld/src/main/java/com/example/ReadingTimeSample.java b/examples/bld/src/main/java/com/example/ReadingTimeSample.java new file mode 100644 index 0000000..5f73ac9 --- /dev/null +++ b/examples/bld/src/main/java/com/example/ReadingTimeSample.java @@ -0,0 +1,35 @@ +package com.example; + +import net.thauvin.erik.readingtime.ReadingTime; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class ReadingTimeSample { + public static void main(String[] args) { + if (args.length >= 1) { + final Path text = Path.of(args[0]); + try { + final ReadingTime rt = new ReadingTime(Files.readString(text)); + rt.setPostfix("minute to read"); + rt.setPlural("minutes to read"); + +// final Config config = +// new Config.Builder(Files.readString(text)) +// .postfix("minute to read") +// .plural("minutes to read") +// .build(); +// final ReadingTime rt = new ReadingTime(config); + + System.out.println("It will take " + rt.calcReadingTime() + ' ' + ReadingTime.wordCount(rt.getText()) + + " words and " + ReadingTime.imgCount(rt.getText()) + " images at " + rt.getWpm() + + " words per minute."); + } catch (IOException e) { + System.err.println("The file could not be read or found."); + } + } else { + System.err.println("Please specify a file as an argument."); + } + } +} diff --git a/examples/src/main/kotlin/com/example/ReadingTimeExample.kt b/examples/bld/src/main/kotlin/com/example/ReadingTimeExample.kt similarity index 87% rename from examples/src/main/kotlin/com/example/ReadingTimeExample.kt rename to examples/bld/src/main/kotlin/com/example/ReadingTimeExample.kt index e230dbe..8563bc6 100644 --- a/examples/src/main/kotlin/com/example/ReadingTimeExample.kt +++ b/examples/bld/src/main/kotlin/com/example/ReadingTimeExample.kt @@ -13,7 +13,7 @@ fun main(args: Array) { println( "It will take ${rt.calcReadingTime()} ${ReadingTime.wordCount(rt.text)} words and " + - "${ReadingTime.imgCount(rt.text)} images at ${rt.wpm} words per minute." + "${ReadingTime.imgCount(rt.text)} images at ${rt.wpm} words per minute." ) } else { System.err.println("The file could not be read or found.") diff --git a/examples/src/main/java/com/example/ReadingTimeSample.java b/examples/bld/src/main/main/java/com/example/ReadingTimeSample.java similarity index 82% rename from examples/src/main/java/com/example/ReadingTimeSample.java rename to examples/bld/src/main/main/java/com/example/ReadingTimeSample.java index 59c469b..faaf6a2 100644 --- a/examples/src/main/java/com/example/ReadingTimeSample.java +++ b/examples/bld/src/main/main/java/com/example/ReadingTimeSample.java @@ -16,8 +16,8 @@ public class ReadingTimeSample { rt.setPlural("minutes to read"); System.out.println("It will take " + rt.calcReadingTime() + ' ' + ReadingTime.wordCount(rt.getText()) - + " words and " + ReadingTime.imgCount(rt.getText()) + " images at " + rt.getWpm() - + " words per minute."); + + " words and " + ReadingTime.imgCount(rt.getText()) + " images at " + rt.getWpm() + + " words per minute."); } catch (IOException e) { System.err.println("The file could not be read or found."); } diff --git a/examples/bld/src/main/main/kotlin/com/example/ReadingTimeExample.kt b/examples/bld/src/main/main/kotlin/com/example/ReadingTimeExample.kt new file mode 100644 index 0000000..8563bc6 --- /dev/null +++ b/examples/bld/src/main/main/kotlin/com/example/ReadingTimeExample.kt @@ -0,0 +1,25 @@ +package com.example + +import net.thauvin.erik.readingtime.ReadingTime +import java.io.File + +fun main(args: Array) { + if (args.isNotEmpty()) { + with(File(args[0])) { + if (exists() && canRead()) { + val rt = ReadingTime(readText()) + rt.postfix = "minute to read" + rt.plural = "minutes to read" + + println( + "It will take ${rt.calcReadingTime()} ${ReadingTime.wordCount(rt.text)} words and " + + "${ReadingTime.imgCount(rt.text)} images at ${rt.wpm} words per minute." + ) + } else { + System.err.println("The file could not be read or found.") + } + } + } else { + System.err.println("Please specify a file as an argument.") + } +} diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts deleted file mode 100644 index ab9c64b..0000000 --- a/examples/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id("org.jetbrains.kotlin.jvm") version "1.4.31" - id("com.github.ben-manes.versions") version "0.38.0" - application -} - -// ./gradlew run --args="example.html" -// ./gradlew runJava --args="example.html" - -repositories { - mavenLocal() - mavenCentral() -} - -dependencies { - implementation("net.thauvin.erik:readingtime:0.9.0") -} - -application { - mainClassName = "com.example.ReadingTimeExampleKt" -} - -tasks { - getByName("run") { - args = listOf("${project.projectDir}/example.html") - } - - register("runJava") { - group = "application" - main = "com.example.ReadingTimeSample" - classpath = sourceSets["main"].runtimeClasspath - args = listOf("${project.projectDir}/example.html") - } -} diff --git a/examples/.gitattributes b/examples/gradle/.gitattributes similarity index 100% rename from examples/.gitattributes rename to examples/gradle/.gitattributes diff --git a/examples/.gitignore b/examples/gradle/.gitignore similarity index 100% rename from examples/.gitignore rename to examples/gradle/.gitignore diff --git a/.idea/.gitignore b/examples/gradle/.idea/.gitignore similarity index 100% rename from .idea/.gitignore rename to examples/gradle/.idea/.gitignore diff --git a/examples/gradle/.idea/.name b/examples/gradle/.idea/.name new file mode 100644 index 0000000..9b7d9ec --- /dev/null +++ b/examples/gradle/.idea/.name @@ -0,0 +1 @@ +readingtime-examples-gradle \ No newline at end of file diff --git a/.idea/compiler.xml b/examples/gradle/.idea/compiler.xml similarity index 75% rename from .idea/compiler.xml rename to examples/gradle/.idea/compiler.xml index 61a9130..fb7f4a8 100644 --- a/.idea/compiler.xml +++ b/examples/gradle/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/examples/gradle/.idea/gradle.iml b/examples/gradle/.idea/gradle.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/examples/gradle/.idea/gradle.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/examples/gradle/.idea/gradle.xml b/examples/gradle/.idea/gradle.xml new file mode 100644 index 0000000..ce1c62c --- /dev/null +++ b/examples/gradle/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/examples/gradle/.idea/inspectionProfiles/Project_Default.xml b/examples/gradle/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1e01b48 --- /dev/null +++ b/examples/gradle/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/examples/gradle/.idea/intellij-javadocs-4.0.1.xml b/examples/gradle/.idea/intellij-javadocs-4.0.1.xml new file mode 100644 index 0000000..5d2c532 --- /dev/null +++ b/examples/gradle/.idea/intellij-javadocs-4.0.1.xml @@ -0,0 +1,204 @@ + + + + + UPDATE + false + true + + METHOD + FIELD + TYPE + + + DEFAULT + PUBLIC + PROTECTED + + + + + + ^.*(public|protected|private)*.+interface\s+\w+.* + /**\n + * The interface ${name}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> + */ + + + ^.*(public|protected|private)*.+enum\s+\w+.* + /**\n + * The enum ${name}.\n + */ + + + ^.*(public|protected|private)*.+class\s+\w+.* + /**\n + * The type ${name}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> + */ + + + .+ + /**\n + * The type ${name}.\n + */ + + + + + .+ + /**\n + * Instantiates a new ${name}.\n +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + + + ^.*(public|protected|private)*\s*.*(\w(\s*<.+>)*)+\s+get\w+\s*\(.*\).+ + /**\n + * Gets ${partName}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if isNotVoid> + *\n + * @return the ${partName}\n +</#if> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + ^.*(public|protected|private)*\s*.*(void|\w(\s*<.+>)*)+\s+set\w+\s*\(.*\).+ + /**\n + * Sets ${partName}.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if isNotVoid> + *\n + * @return the ${partName}\n +</#if> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + ^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+ + /**\n + * The entry point of application.\n + + <#if element.parameterList.parameters?has_content> + *\n +</#if> + * @param ${element.parameterList.parameters[0].name} the input arguments\n +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + .+ + /**\n + * ${name}<#if isNotVoid> ${return}</#if>.\n +<#if element.typeParameters?has_content> * \n +</#if> +<#list element.typeParameters as typeParameter> + * @param <${typeParameter.name}> the type parameter\n +</#list> +<#if element.parameterList.parameters?has_content> + *\n +</#if> +<#list element.parameterList.parameters as parameter> + * @param ${parameter.name} the ${paramNames[parameter.name]}\n +</#list> +<#if isNotVoid> + *\n + * @return the ${return}\n +</#if> +<#if element.throwsList.referenceElements?has_content> + *\n +</#if> +<#list element.throwsList.referenceElements as exception> + * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n +</#list> + */ + + + + + ^.*(public|protected|private)*.+static.*(\w\s\w)+.+ + /**\n + * The constant ${element.getName()}.\n + */ + + + ^.*(public|protected|private)*.*(\w\s\w)+.+ + /**\n + <#if element.parent.isInterface()> + * The constant ${element.getName()}.\n +<#else> + * The ${name}.\n +</#if> */ + + + .+ + /**\n + <#if element.parent.isEnum()> + *${name} ${typeName}.\n +<#else> + * The ${name}.\n +</#if>*/ + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/examples/gradle/.idea/jarRepositories.xml similarity index 69% rename from .idea/jarRepositories.xml rename to examples/gradle/.idea/jarRepositories.xml index b9c41fe..4e9cedf 100644 --- a/.idea/jarRepositories.xml +++ b/examples/gradle/.idea/jarRepositories.xml @@ -11,15 +11,20 @@