185 lines
4.9 KiB
Text
185 lines
4.9 KiB
Text
import "./pattern" for Pattern
|
||
import "./str" for Str
|
||
import "./fmt" for Fmt
|
||
import "./sort" for Cmp, Sort
|
||
|
||
var p2 = Pattern.new("+2 ")
|
||
var p3 = Pattern.new("/s") // any whitespace character
|
||
var p5 = Pattern.new("+1/d")
|
||
|
||
/** Only covers ISO-8859-1 accented characters plus (for consistency) Ÿ */
|
||
var ucAccented = ["ÀÁÂÃÄÅ", "Ç", "ÈÉÊË", "ÌÍÎÏ", "Ñ", "ÒÓÔÕÖØ", "ÙÚÛÜ", "ÝŸ"]
|
||
var lcAccented = ["àáâãäå", "ç", "èéêë", "ìíîï", "ñ", "òóôõöø", "ùúûü", "ýÿ"]
|
||
var ucNormal = "ACEINOUY"
|
||
var lcNormal = "aceinouy"
|
||
|
||
/** Only the commoner ligatures */
|
||
var ucLigatures = "ÆIJŒ"
|
||
var lcLigatures = "æijœ"
|
||
var ucSeparated = ["AE", "IJ", "OE"]
|
||
var lcSeparated = ["ae", "ij", "oe"]
|
||
|
||
/** Miscellaneous replacements */
|
||
var miscLetters = "ßſʒ"
|
||
var miscReplacements = ["ss", "s", "s"]
|
||
|
||
/** Displays strings including whitespace as if the latter were literal characters */
|
||
var toDisplayString = Fn.new { |s|
|
||
var whitespace = ["\t", "\n", "\v", "\f", "\r"]
|
||
var whitespace2 = ["\\t", "\\n", "\\v", "\\f", "\\r"]
|
||
for (i in 0..4) s = s.replace(whitespace[i], whitespace2[i])
|
||
return s
|
||
}
|
||
|
||
/** Ignoring leading space(s) */
|
||
var selector1 = Fn.new { |s| s.trimStart(" ") }
|
||
|
||
/** Ignoring multiple adjacent spaces i.e. condensing to a single space */
|
||
var selector2 = Fn.new { |s| p2.replaceAll(s, " ") }
|
||
|
||
/** Equivalent whitespace characters (equivalent to a space say) */
|
||
var selector3 = Fn.new { |s| p3.replaceAll(s, " ") }
|
||
|
||
/** Case independent sort */
|
||
var selector4 = Fn.new { |s| Str.lower(s) }
|
||
|
||
/** Numeric fields as numerics (deals with up to 20 digits) */
|
||
var selector5 = Fn.new { |s|
|
||
for (m in p5.findAll(s)) {
|
||
var ix = m.index
|
||
var repl = Fmt.swrite("$020d", Num.fromString(m.text))
|
||
s = s[0...ix] + repl + s[ix + m.length..-1]
|
||
}
|
||
return s
|
||
}
|
||
|
||
/** Title sort */
|
||
var selector6 = Fn.new { |s|
|
||
var t = Str.lower(s)
|
||
if (t.startsWith("the ")) return s.skip(4).join()
|
||
if (t.startsWith("an ")) return s.skip(3).join()
|
||
if (t.startsWith("a ")) return s.skip(2).join()
|
||
return s
|
||
}
|
||
|
||
/** Equivalent accented characters (and case) */
|
||
var selector7 = Fn.new { |s|
|
||
var sb = ""
|
||
for (c in s) {
|
||
var outer = false
|
||
var i = 0
|
||
for (ucs in ucAccented) {
|
||
if (ucs.contains(c)) {
|
||
sb = sb + ucNormal[i]
|
||
outer = true
|
||
break
|
||
}
|
||
i = i + 1
|
||
}
|
||
if (outer) continue
|
||
i = 0
|
||
for (lcs in lcAccented) {
|
||
if (lcs.contains(c)) {
|
||
sb = sb + lcNormal[i]
|
||
outer = true
|
||
break
|
||
}
|
||
i = i + 1
|
||
}
|
||
if (outer) continue
|
||
sb = sb + c
|
||
}
|
||
return Str.lower(sb)
|
||
}
|
||
|
||
/** Separated ligatures */
|
||
var selector8 = Fn.new { |s|
|
||
var i = 0
|
||
for (c in ucLigatures) {
|
||
s = s.replace(c, ucSeparated[i])
|
||
i = i + 1
|
||
}
|
||
i = 0
|
||
for (c in lcLigatures) {
|
||
s = s.replace(c, lcSeparated[i])
|
||
i = i + 1
|
||
}
|
||
return s
|
||
}
|
||
|
||
/** Character replacements */
|
||
var selector9 = Fn.new { |s|
|
||
var i = 0
|
||
for (c in miscLetters) {
|
||
s = s.replace(c, miscReplacements[i])
|
||
i = i + 1
|
||
}
|
||
return s
|
||
}
|
||
|
||
System.print("The 9 string lists, sorted 'naturally':\n")
|
||
var selectors = [selector1, selector2, selector3, selector4, selector5,
|
||
selector6, selector7, selector8, selector9]
|
||
var ss = [
|
||
[
|
||
"ignore leading spaces: 2-2",
|
||
" ignore leading spaces: 2-1",
|
||
" ignore leading spaces: 2+0",
|
||
" ignore leading spaces: 2+1"
|
||
],
|
||
[
|
||
"ignore m.a.s spaces: 2-2",
|
||
"ignore m.a.s spaces: 2-1",
|
||
"ignore m.a.s spaces: 2+0",
|
||
"ignore m.a.s spaces: 2+1"
|
||
],
|
||
[
|
||
"Equiv. spaces: 3-3",
|
||
"Equiv.\rspaces: 3-2",
|
||
"Equiv.\vspaces: 3-1",
|
||
"Equiv.\fspaces: 3+0",
|
||
"Equiv.\nspaces: 3+1",
|
||
"Equiv.\tspaces: 3+2"
|
||
],
|
||
[
|
||
"cASE INDEPENENT: 3-2",
|
||
"caSE INDEPENENT: 3-1",
|
||
"casE INDEPENENT: 3+0",
|
||
"case INDEPENENT: 3+1"
|
||
],
|
||
[
|
||
"foo100bar99baz0.txt",
|
||
"foo100bar10baz0.txt",
|
||
"foo1000bar99baz10.txt",
|
||
"foo1000bar99baz9.txt"
|
||
],
|
||
[
|
||
"The Wind in the Willows",
|
||
"The 40th step more",
|
||
"The 39 steps",
|
||
"Wanda"
|
||
],
|
||
[
|
||
"Equiv. ý accents: 2-2",
|
||
"Equiv. Ý accents: 2-1",
|
||
"Equiv. y accents: 2+0",
|
||
"Equiv. Y accents: 2+1"
|
||
],
|
||
[
|
||
"IJ ligatured ij",
|
||
"no ligature"
|
||
],
|
||
[
|
||
"Start with an ʒ: 2-2",
|
||
"Start with an ſ: 2-1",
|
||
"Start with an ß: 2+0",
|
||
"Start with an s: 2+1"
|
||
]
|
||
]
|
||
for (i in 0..8) {
|
||
var sel = selectors[i]
|
||
var cmp = Fn.new { |s1, s2| Cmp.string.call(sel.call(s1), sel.call(s2)) }
|
||
Sort.insertion(ss[i], cmp)
|
||
System.print(ss[i].map { |s| "'%(s)'" }.join("\n"))
|
||
if (i < 8) System.print()
|
||
}
|