summaryrefslogtreecommitdiff
path: root/stringmetric-cli/source/core/scala/com/rockymadden
diff options
context:
space:
mode:
Diffstat (limited to 'stringmetric-cli/source/core/scala/com/rockymadden')
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/Command.scala24
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionMap.scala38
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionString.scala30
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/package.scala13
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonealgorithm.scala41
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonemetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiisalgorithm.scala41
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiismetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiisalgorithm.scala41
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiismetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexalgorithm.scala41
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexmetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexalgorithm.scala41
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexmetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/dicesorensenmetric.scala49
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/hammingmetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jaccardmetric.scala49
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarometric.scala41
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarowinklermetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/levenshteinmetric.scala45
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ngrammetric.scala49
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/overlapmetric.scala49
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ratcliffobershelpmetric.scala44
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/weightedlevenshteinmetric.scala62
-rwxr-xr-xstringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/tokenization/ngramtokenizer.scala58
25 files changed, 1064 insertions, 0 deletions
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/Command.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/Command.scala
new file mode 100755
index 0000000..fedc0d9
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/Command.scala
@@ -0,0 +1,24 @@
+package com.rockymadden.stringmetric.cli
+
+/** Defines the traits and provides basic implementations of a command. Commands are always implemented as objects. */
+trait Command {
+ def help(): Unit
+
+ final def error(error: Throwable, options: OptionMap): Unit =
+ if (!isUnitTest(options)) {
+ println(error.getMessage)
+ sys.exit(1)
+ } else throw error
+
+ def execute(options: OptionMap): Unit
+
+ final def exit(options: OptionMap): Unit = if (!isUnitTest(options)) sys.exit(0)
+
+ final protected[this] def isDebug(options: OptionMap): Boolean =
+ (options.contains('d) || (options.contains('debug) && options.get('debug) != "false"))
+
+ final protected[this] def isUnitTest(options: OptionMap): Boolean =
+ (options.contains('ut) || (options.contains('unitTest) && options.get('unitTest) != "false"))
+
+ def main(args: Array[String]): Unit
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionMap.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionMap.scala
new file mode 100755
index 0000000..79aea0b
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionMap.scala
@@ -0,0 +1,38 @@
+package com.rockymadden.stringmetric.cli
+
+import scala.annotation.tailrec
+
+object OptionMap {
+ def apply(args: Array[String]): OptionMap = apply(args: _*)
+
+ def apply(varargs: String*): OptionMap = {
+ @tailrec
+ def next(om: OptionMap, a: List[String]): OptionMap = {
+ val double = """^(--[a-zA-Z0-9]+)(=[a-zA-Z0-9\.\-_]+)?""".r
+ val single = """^(-[a-zA-Z0-9]+)(=[a-zA-Z0-9\.\-_]+)?""".r
+ val less = """([a-zA-Z0-9/\-_\$\.]+)""".r
+
+ a match {
+ // Empty, return.
+ case Nil => om
+ // Double dash options without value.
+ case double(k, null) :: t => next(om + (Symbol(k.tail.tail) -> ""), t)
+ // Double dash options with value.
+ case double(k, v) :: t => next(om + (Symbol(k.tail.tail) -> v.tail), t)
+ // Single dash options without value.
+ case single(k, null) :: t => next(om + (Symbol(k.tail) -> ""), t)
+ // Single dash options with value. Value is discarded.
+ case single(k, v) :: t => next(om + (Symbol(k.tail) -> ""), t)
+ // Dashless options.
+ case less(v) :: t if v.head != '-' =>
+ if (om.contains('dashless))
+ next((om - 'dashless) + ('dashless -> (om('dashless).self + " " + v.trim)), t)
+ else next(om + ('dashless -> v.trim), t)
+ // Invalid option, ignore.
+ case _ :: t => next(om, t)
+ }
+ }
+
+ next(Map.empty[Symbol, OptionString], varargs.toList)
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionString.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionString.scala
new file mode 100755
index 0000000..7a1350d
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/OptionString.scala
@@ -0,0 +1,30 @@
+package com.rockymadden.stringmetric.cli
+
+import scala.language.implicitConversions
+
+class OptionString(val self: String)
+
+object OptionString {
+ implicit def OptionStringToArray(optionString: OptionString): Array[String] =
+ if (optionString.self.length == 0) Array.empty[String] else optionString.self.split(" ")
+
+ implicit def OptionStringToBigDecimal(optionString: OptionString): BigDecimal = BigDecimal(optionString.self)
+
+ implicit def OptionStringToBigInt(optionString: OptionString): BigInt = BigInt(optionString.self)
+
+ implicit def OptionStringToDouble(optionString: OptionString): Double = optionString.self.toDouble
+
+ implicit def OptionStringToFloat(optionString: OptionString): Float = optionString.self.toFloat
+
+ implicit def OptionStringToInt(optionString: OptionString): Int = optionString.self.toInt
+
+ implicit def OptionStringToLong(optionString: OptionString): Long = optionString.self.toLong
+
+ implicit def OptionStringToShort(optionString: OptionString): Short = optionString.self.toShort
+
+ implicit def OptionStringToString(optionString: OptionString): String = optionString.self
+
+ implicit def StringToOptionString(string: String): OptionString = apply(string)
+
+ def apply(string: String): OptionString = new OptionString(string)
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/package.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/package.scala
new file mode 100755
index 0000000..cbaba97
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/package.scala
@@ -0,0 +1,13 @@
+package com.rockymadden.stringmetric
+
+import scala.language.implicitConversions
+
+/**
+ * Provides core CLI functionality. Note that some things might look sloppy (e.g. access modifiers, broad imports,
+ * repetitive imports, etc), but are required because of the way scalascript is ultimately compiled.
+ */
+package object cli {
+ type OptionMap = Map[Symbol, OptionString]
+
+ implicit def StringArrayToOptionMap(stringArray: Array[String]): OptionMap = OptionMap(stringArray)
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonealgorithm.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonealgorithm.scala
new file mode 100755
index 0000000..d0b3812
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonealgorithm.scala
@@ -0,0 +1,41 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.MetaphoneAlgorithm
+
+/**
+ * The metaphonealgorithm [[com.rockymadden.stringmetric.cli.Command]]. Returns the phonetic representation of the
+ * passed string, per the Metaphone algorithm.
+ */
+object metaphonealgorithm extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 1) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Returns the phonetic representation of the passed string, per the Metaphone algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "metaphonealgorithm [Options] string..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit =
+ println(MetaphoneAlgorithm.compute(opts('dashless)).getOrElse("not computable"))
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonemetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonemetric.scala
new file mode 100755
index 0000000..98ac85c
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/metaphonemetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.MetaphoneMetric
+
+/**
+ * The metaphonemetric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to determine if they are
+ * phonetically similarly, per the Metaphone algorithm.
+ */
+object metaphonemetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to determine if they are phonetically similarly, per the Metaphone algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "metaphonemetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+
+ println(MetaphoneMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiisalgorithm.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiisalgorithm.scala
new file mode 100755
index 0000000..0770ba5
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiisalgorithm.scala
@@ -0,0 +1,41 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.NysiisAlgorithm
+
+/**
+ * The nysiisalgorithm [[com.rockymadden.stringmetric.cli.Command]]. Returns the phonetic representation of the passed
+ * string, per the NYSIIS algorithm.
+ */
+object nysiisalgorithm extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 1) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Returns the phonetic representation of the passed string, per the NYSIIS algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "nysiisalgorithm [Options] string..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit =
+ println(NysiisAlgorithm.compute(options('dashless)).getOrElse("not computable"))
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiismetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiismetric.scala
new file mode 100755
index 0000000..95ece48
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/nysiismetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.NysiisMetric
+
+/**
+ * The nysiismetric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to determine if they are
+ * phonetically similarly, per the NYSIIS algorithm.
+ */
+object nysiismetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to determine if they are phonetically similarly, per the NYSIIS algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "nysiismetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+
+ println(NysiisMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiisalgorithm.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiisalgorithm.scala
new file mode 100755
index 0000000..e155cbf
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiisalgorithm.scala
@@ -0,0 +1,41 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.RefinedNysiisAlgorithm
+
+/**
+ * The refinednysiisalgorithm [[com.rockymadden.stringmetric.cli.Command]]. Returns the phonetic representation of the
+ * passed string, per the refined NYSIIS algorithm.
+ */
+object refinednysiisalgorithm extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 1) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Returns the phonetic representation of the passed string, per the refined NYSIIS algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "refinednysiisalgorithm [Options] string..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit =
+ println(RefinedNysiisAlgorithm.compute(opts('dashless)).getOrElse("not computable"))
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiismetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiismetric.scala
new file mode 100755
index 0000000..3c32291
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinednysiismetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.RefinedNysiisMetric
+
+/**
+ * The refinednysiismetric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to determine if they are
+ * phonetically similarly, per the refined NYSIIS algorithm.
+ */
+object refinednysiismetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to determine if they are phonetically similarly, per the refined NYSIIS algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "refinednysiismetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+
+ println(RefinedNysiisMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexalgorithm.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexalgorithm.scala
new file mode 100755
index 0000000..f5a89a8
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexalgorithm.scala
@@ -0,0 +1,41 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.RefinedSoundexAlgorithm
+
+/**
+ * The refinedsoundexalgorithm [[com.rockymadden.stringmetric.cli.Command]]. Returns the phonetic representation of the
+ * passed string, per the refined Soundex algorithm.
+ */
+object refinedsoundexalgorithm extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 1) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Returns the phonetic representation of the passed string, per the refined Soundex algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "refinedsoundexalgorithm [Options] string..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit =
+ println(RefinedSoundexAlgorithm.compute(opts('dashless)).getOrElse("not computable"))
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexmetric.scala
new file mode 100755
index 0000000..e5ea4b4
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/refinedsoundexmetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.RefinedSoundexMetric
+
+/**
+ * The refinedsoundexmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to determine if they are
+ * phonetically similarly, per the refined Soundex algorithm.
+ */
+object refinedsoundexmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to determine if they are phonetically similarly, per the refined Soundex algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "refinedsoundexmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+
+ println(RefinedSoundexMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexalgorithm.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexalgorithm.scala
new file mode 100755
index 0000000..9883eb3
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexalgorithm.scala
@@ -0,0 +1,41 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.SoundexAlgorithm
+
+/**
+ * The soundexalgorithm [[com.rockymadden.stringmetric.cli.Command]]. Returns the phonetic representation of the passed
+ * string, per the Soundex algorithm.
+ */
+object soundexalgorithm extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 1) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Returns the phonetic representation of the passed string, per the Soundex algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "soundexalgorithm [Options] string..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit =
+ println(SoundexAlgorithm.compute(opts('dashless)).getOrElse("not computable"))
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexmetric.scala
new file mode 100755
index 0000000..01d070e
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/phonetic/soundexmetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.phonetic
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.phonetic.SoundexMetric
+
+/**
+ * The soundexmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to determine if they are
+ * phonetically similarly, per the Soundex algorithm.
+ */
+object soundexmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to determine if they are phonetically similarly, per the Soundex algorithm." + ls + ls +
+ "Syntax:" + ls +
+ tab + "soundexmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+
+ println(SoundexMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/dicesorensenmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/dicesorensenmetric.scala
new file mode 100755
index 0000000..5d0e234
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/dicesorensenmetric.scala
@@ -0,0 +1,49 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.DiceSorensenMetric
+
+/**
+ * The dicesorensenmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the similarity of two strings using the
+ * Dice / Sorensen coefficient.
+ */
+object dicesorensenmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2
+ && opts.contains('n) && (opts('n): Int) >= 1) {
+
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the similarity of two strings using the Dice / Sorensen coefficient." + ls + ls +
+ "Syntax:" + ls +
+ tab + "dicesorensenmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts." +
+ tab + "--n" + ls +
+ tab + tab + "The n-gram size, traditionally 2."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+ val n: Int = opts('n)
+
+ println(DiceSorensenMetric.compare(strings(0), strings(1))(n).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/hammingmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/hammingmetric.scala
new file mode 100755
index 0000000..c03293f
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/hammingmetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.HammingMetric
+
+/**
+ * The hammingmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the number of characters that two equal
+ * length strings are different from one another.
+ */
+object hammingmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the number of characters that two equal length strings are different from one another." + ls + ls +
+ "Syntax:" + ls +
+ tab + "hammingmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+
+ println(HammingMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jaccardmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jaccardmetric.scala
new file mode 100755
index 0000000..1f1e123
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jaccardmetric.scala
@@ -0,0 +1,49 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.JaccardMetric
+
+/**
+ * The jaccardmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the similarity of two strings using the
+ * Jaccard coefficient.
+ */
+object jaccardmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2
+ && opts.contains('n) && (opts('n): Int) >= 1) {
+
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the similarity of two strings using the Jaccard coefficient." + ls + ls +
+ "Syntax:" + ls +
+ tab + "jaccardmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts." +
+ tab + "--n" + ls +
+ tab + tab + "The n-gram size."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+ val n: Int = opts('n)
+
+ println(JaccardMetric.compare(strings(0), strings(1))(n).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarometric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarometric.scala
new file mode 100755
index 0000000..fcb6aa2
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarometric.scala
@@ -0,0 +1,41 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.JaroMetric
+
+/** The jarometric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to calculate the Jaro distance. */
+object jarometric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to calculate the Jaro distance." + ls + ls +
+ "Syntax:" + ls +
+ tab + "jarometric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+
+ println(JaroMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarowinklermetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarowinklermetric.scala
new file mode 100755
index 0000000..b925c2d
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/jarowinklermetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.JaroWinklerMetric
+
+/**
+ * The jarowinklermetric [[com.rockymadden.stringmetric.cli.Command]]. Compares two strings to calculate the
+ * Jaro-Winkler distance.
+ */
+object jarowinklermetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares two strings to calculate the Jaro-Winkler distance." + ls + ls +
+ "Syntax:" + ls +
+ tab + "jarowinklermetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+
+ println(JaroWinklerMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/levenshteinmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/levenshteinmetric.scala
new file mode 100755
index 0000000..6146750
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/levenshteinmetric.scala
@@ -0,0 +1,45 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.LevenshteinMetric
+
+/**
+ * The levenshteinmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the number of characters that two
+ * strings are different from one another via insertion, deletion, and substitution.
+ */
+object levenshteinmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2) {
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the number of characters that two strings are different from one another via insertion, deletion, " +
+ "and substitution." + ls + ls +
+ "Syntax:" + ls +
+ tab + "levenshteinmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+
+ println(LevenshteinMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ngrammetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ngrammetric.scala
new file mode 100755
index 0000000..af0634f
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ngrammetric.scala
@@ -0,0 +1,49 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.NGramMetric
+
+/**
+ * The ngrammetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the similarity of two strings using an N-Gram
+ * similarity index.
+ */
+object ngrammetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val options: OptionMap = args
+
+ try
+ if (options.contains('h) || options.contains('help)) {
+ help()
+ exit(options)
+ } else if (options.contains('dashless) && (options('dashless): Array[String]).length == 2
+ && options.contains('n) && (options('n): Int) >= 1) {
+
+ execute(options)
+ exit(options)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, options) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the similarity of two strings using an N-Gram similarity index." + ls + ls +
+ "Syntax:" + ls +
+ tab + "ngrammetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and options." +
+ tab + "--n" + ls +
+ tab + tab + "The n."
+ )
+ }
+
+ override def execute(options: OptionMap): Unit = {
+ val strings: Array[String] = options('dashless)
+ val n: Int = options('n)
+
+ println(NGramMetric.compare(strings(0), strings(1))(n).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/overlapmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/overlapmetric.scala
new file mode 100755
index 0000000..2c670c5
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/overlapmetric.scala
@@ -0,0 +1,49 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.OverlapMetric
+
+/**
+ * The overlapmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the similarity of two strings using the
+ * overlap coefficient.
+ */
+object overlapmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2
+ && opts.contains('n) && (opts('n): Int) >= 1) {
+
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the similarity of two strings using the overlap coefficient." + ls + ls +
+ "Syntax:" + ls +
+ tab + "overlapmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts." +
+ tab + "--n" + ls +
+ tab + tab + "The n-gram size."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+ val n: Int = opts('n)
+
+ println(OverlapMetric.compare(strings(0), strings(1))(n).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ratcliffobershelpmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ratcliffobershelpmetric.scala
new file mode 100755
index 0000000..f69c222
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/ratcliffobershelpmetric.scala
@@ -0,0 +1,44 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.RatcliffObershelpMetric
+
+/**
+ * The ratcliffobershelpmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the similarity of two strings
+ * using the Ratcliff / Obershelp similarity index.
+ */
+object ratcliffobershelpmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2) {
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the similarity of two strings using the Ratcliff / Obershelp similarity index." + ls + ls +
+ "Syntax:" + ls +
+ tab + "ratcliffobershelpmetric [Options] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+
+ println(RatcliffObershelpMetric.compare(strings(0), strings(1)).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/weightedlevenshteinmetric.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/weightedlevenshteinmetric.scala
new file mode 100755
index 0000000..d675db1
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/similarity/weightedlevenshteinmetric.scala
@@ -0,0 +1,62 @@
+package com.rockymadden.stringmetric.cli.similarity
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.similarity.WeightedLevenshteinMetric
+import scala.math.BigDecimal
+
+/**
+ * The weightedlevenshteinmetric [[com.rockymadden.stringmetric.cli.Command]]. Compares the number of characters that
+ * two strings are different from one another via insertion, deletion, and substitution. Allows the invoker to indicate
+ * the weight each operation takes.
+ */
+object weightedlevenshteinmetric extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 2
+ && opts.contains('deleteWeight) && (opts('deleteWeight): Double) >= 0
+ && opts.contains('insertWeight) && (opts('insertWeight): Double) >= 0
+ && opts.contains('substituteWeight) && (opts('substituteWeight): Double) >= 0) {
+
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Compares the number of characters that two strings are different from one another via insertion, deletion, " +
+ "and substitution. Allows the invoker to indicate the weight each operation takes." + ls + ls +
+ "Syntax:" + ls +
+ tab + "weightedlevenshteinmetric [Options] --deleteWeight=[double] --insertWeight=[double] --substituteWeight=[double] string1 string2..." + ls + ls +
+ "Options:" + ls +
+ tab + "--deleteWeight" + ls +
+ tab + tab + "The weight given to delete operations." +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts." +
+ tab + "--insertWeight" + ls +
+ tab + tab + "The weight given to insert operations." +
+ tab + "--substituteWeight" + ls +
+ tab + tab + "The weight given to substitute operations."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit = {
+ val strings: Array[String] = opts('dashless)
+ val weights = Tuple3[BigDecimal, BigDecimal, BigDecimal](
+ opts('deleteWeight),
+ opts('insertWeight),
+ opts('substituteWeight)
+ )
+
+ println(WeightedLevenshteinMetric.compare(strings(0), strings(1))(weights).getOrElse("not comparable"))
+ }
+}
diff --git a/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/tokenization/ngramtokenizer.scala b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/tokenization/ngramtokenizer.scala
new file mode 100755
index 0000000..99fdbe5
--- /dev/null
+++ b/stringmetric-cli/source/core/scala/com/rockymadden/stringmetric/cli/tokenization/ngramtokenizer.scala
@@ -0,0 +1,58 @@
+package com.rockymadden.stringmetric.cli.tokenization
+
+import com.rockymadden.stringmetric.cli._
+import com.rockymadden.stringmetric.tokenization.NGramTokenizer
+
+/**
+ * The ngramtokenizer [[com.rockymadden.stringmetric.cli.Command]]. Returns the N-Gram representation of the passed
+ * string.
+ */
+object ngramtokenizer extends Command {
+ override def main(args: Array[String]): Unit = {
+ val opts: OptionMap = args
+
+ try
+ if (opts.contains('h) || opts.contains('help)) {
+ help()
+ exit(opts)
+ } else if (opts.contains('dashless) && (opts('dashless): Array[String]).length == 1
+ && opts.contains('n) && (opts('n): Int) >= 1) {
+
+ execute(opts)
+ exit(opts)
+ } else throw new IllegalArgumentException("Expected valid syntax. See --help.")
+ catch { case e: Throwable => error(e, opts) }
+ }
+
+ override def help(): Unit = {
+ val ls = sys.props("line.separator")
+ val tab = " "
+
+ println(
+ "Returns the N-Gram representation of the passed string." + ls + ls +
+ "Syntax:" + ls +
+ tab + "ngramtokenizer [Options] string..." + ls + ls +
+ "Options:" + ls +
+ tab + "-h, --help" + ls +
+ tab + tab + "Outputs description, syntax, and opts." +
+ tab + "--n" + ls +
+ tab + tab + "The n."
+ )
+ }
+
+ override def execute(opts: OptionMap): Unit =
+ NGramTokenizer.tokenize(opts('dashless))(opts('n)) match {
+ // Implicits are a pain here.
+ case Some(c) => {
+ val sb = new StringBuilder
+
+ Range(0, c.length).foreach { i =>
+ sb.append(c(i))
+ if (i < c.length - 1) sb.append("|")
+ }
+
+ println(sb.result())
+ }
+ case None => println("not computable")
+ }
+}