59 lines
2.3 KiB
Text
59 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);
|