58 lines
2.3 KiB
Text
58 lines
2.3 KiB
Text
def splitup:
|
||
def tidy: if .[0] == "" then .[1:] else . end | if .[length-1] == "" then .[0:length-1] else . end ;
|
||
|
||
# a and b are assumed to be arrays:
|
||
def alternate(a;b):
|
||
reduce range(0; [a,b] | map(length) | max) as $i ([]; . + [a[$i], b[$i]]);
|
||
|
||
([splits("[0-9]+")] | tidy) as $a
|
||
| ([splits("[^0-9]+")] | tidy | map(tonumber)) as $n
|
||
| (test("^[0-9]")) as $nfirst
|
||
| if $nfirst then alternate($n; $a) else alternate($a; $n) end ;
|
||
|
||
# The following implementation of tr is more general than needed here, but the generality
|
||
# makes for adaptability.
|
||
# x and y should both be strings defining a character-by-character translation, like Unix/Linux "tr".
|
||
# if y is shorter than x, then y will in effect be padded with y's last character.
|
||
# The input may be a string or an exploded string (i.e. an array);
|
||
# the output will have the same type as the input.
|
||
def tr(x;y):
|
||
type as $type
|
||
| (x | explode) as $xe
|
||
| (y | explode) as $ye
|
||
| $ye[-1] as $last
|
||
| if $type == "string" then explode else . end
|
||
| map( . as $n | ($xe|index($n)) as $i | if $i then $ye[$i]//$last else . end)
|
||
| if $type == "string" then implode else . end;
|
||
|
||
# NOTE: the order in which the filters are applied is consequential!
|
||
def natural_sort:
|
||
def naturally:
|
||
gsub("\\p{M}"; "") # combining characters (accents, umlauts, enclosures, etc)
|
||
| tr("ÀÁÂÃÄÅàáâãäåÇçÈÉÊËèéêëÌÍÎÏìíîïÒÓÔÕÖØòóôõöøÑñÙÚÛÜùúûüÝÿý";
|
||
"AAAAAAaaaaaaCcEEEEeeeeIIIIiiiiOOOOOOooooooNnUUUUuuuuYyy")
|
||
# Ligatures:
|
||
| gsub("Æ"; "AE")
|
||
| gsub("æ"; "ae")
|
||
| gsub("\u0132"; "IJ") # IJ
|
||
| gsub("\u0133"; "ij") # ij
|
||
| gsub("\u0152"; "Oe") # Œ
|
||
| gsub("\u0153"; "oe") # œ
|
||
| gsub("ffl"; "ffl")
|
||
| gsub("ffi"; "ffi")
|
||
| gsub("fi" ; "fi")
|
||
| gsub("ff" ; "ff")
|
||
| gsub("fl" ; "fl")
|
||
# Illustrative replacements:
|
||
| gsub("ß" ; "ss") # German scharfes S
|
||
| gsub("ſ|ʒ"; "s") # LATIN SMALL LETTER LONG S and LATIN SMALL LETTER EZH
|
||
|
||
| ascii_downcase
|
||
| gsub("\\p{Cc}+";" ") # control characters
|
||
| gsub("^(the|a|an) "; "") # leading the/a/an (as words)
|
||
| gsub("\\s+"; " ") # whitespace
|
||
| sub("^ *";"") # leading whitespace
|
||
| sub(" *$";"") # trailing whitespace
|
||
| splitup # embedded integers
|
||
;
|
||
sort_by(naturally);
|