9a3e3b612f058a404f00995f8f1d94cdc1a7c100
[torn.git] / torn.zsh
1 # torn - Musical files renaming with russian language transliteration
2 # Copyright (C) 2007-2022 Sergey Matveev (stargrave@stargrave.org)
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, version 3 of the License.
7
8 # Initially this script was written on Perl, but now it is zsh function,
9 # that is intended to be used with zmv command. It is much more flexible
10 # to be used with zsh'es glob expansion.
11 #
12 # * transliterates everything
13 # * replaces spaces with underscores
14 # * lowercases file's extension
15 # * replaces "_-_" with single dash
16 # * removes spaces before and after brackets
17 # * removes space after comma
18 # * removes "[]" brackets
19 # * replaces ampersand with "and" word
20 #
21 # You can run like that:
22 #   $ fpath=(... $fpath)
23 #   $ autoload torn
24 #   $ zmv "*" '`torn $f`"
25 #
26 # Transliteration function is separate tornt(), so you can use only
27 # its abilities:
28 #   $ torn # assume that it is not autoloaded
29 #   $ zmv "*" '`tornt $f`'
30 #
31 # Recursively dive into subdirectories:
32 #   $ zmv -Q "(**/)*(.)" '`torn $f`'
33
34 tornt() {
35     local n=$1
36     local rusS=абвгдеёзийклмнопрстуфхцьъыэ
37     local engS=abvgdeezijklmnoprstufhcjjye
38     for i ({1..${#rusS}}) {
39         eval n=\${n:gs/${rusS[$i]}/${engS[$i]}}
40         eval n=\${n:gs/${(U)rusS[$i]}/${(U)engS[$i]}}
41     }
42     local rusL=( ж  ч  ш   щ  я  ю  Ж  Ч  Ш   Щ  Я  Ю)
43     local engL=(zh ch sh sch ja ju Zh Ch Sh Sch Ja Ju)
44     for i ({1..${#rusL}}) eval n=\${n:gs/${rusL[$i]}/${engL[$i]}}
45     print $n
46 }
47
48 tornm() {
49     local n=$1
50     n=${n:gs/ /_}
51     n=${n//_[–-]_/-}
52     n=${n:gs/,_/,}
53     n=${n//[\[\]]/}
54     n=${n:gs/_(/(}
55     n=${n:gs/-(/-}
56     n=${n:gs/(_/(}
57     n=${n:gs/)_/-}
58     n=${n:gs/_)/)}
59     n=${n:gs/&/and}
60     [[ $n =~ "\." ]] && n=${n:r}.${(L)n:e}
61     [[ $n =~ "^([[:digit:]]+)[-.]_*(.+)$" ]] && n="$match[1].$match[2]"
62     print $n
63 }
64
65 local n=${1:t}
66 n=`tornm $n`
67 n=`tornt $n`
68 print ${1:h}/$n