forked from i-tu/Hasklig
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gen_calt.clj
150 lines (125 loc) · 4.38 KB
/
gen_calt.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
(comment "
Modified 2016 under the terms of SIL for use in Hasklig.
Ian Tuomi
Copyright (c) 2014, Nikita Prokopov http://tonsky.me
with Reserved Font Name Fira Code.
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
with Reserved Font Name Fira Sans.
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
with Reserved Font Name Fira Mono.
Copyright (c) 2014, Telefonica S.A.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
")
#^:shebang '[
exec java -cp "$HOME/.m2/repository/org/clojure/clojure/1.7.0/clojure-1.7.0.jar" clojure.main "$0" "$@"]
(require '[clojure.string :as str])
(def ligas
[ ["asterisk" "asterisk" "asterisk"]
;["bar" "bar" "bar"]
["equal" "equal" "equal"]
["equal" "equal" "greater"]
["equal" "less" "less"]
["greater" "greater" "equal"]
["greater" "greater" "greater"]
["greater" "greater" "hyphen"]
["hyphen" "less" "less"]
["less" "asterisk" "greater"]
["less" "bar" "greater"]
["less" "dollar" "greater"]
["less" "plus" "greater"]
["less" "less" "less"]
["period" "period" "period"]
["plus" "plus" "plus"]
["asterisk" "greater"]
["backslash" "backslash"]
["bar" "bar"]
["bar" "greater"]
["colon" "colon"]
["equal" "equal"]
["equal" "greater"]
["exclam" "exclam"]
["greater" "greater"]
["greater" "hyphen"]
["hyphen" "greater"]
["hyphen" "less"]
["less" "asterisk"]
["less" "greater"]
["less" "bar"]
["less" "hyphen"]
["less" "less"]
["period" "period"]
["plus" "plus"]
["slash" "equal"]])
(defn liga->rules
"[f f i] => { [CR CR i] f_f_i
[CR f i] CR
[ f f i] CR }"
[liga CR]
(case (count liga)
2 (let [[a b] liga]
{ [CR b] (str a "_" b)
[ a b] CR})
3 (let [[a b c] liga]
{ [CR CR c] (str a "_" b "_" c)
[CR b c] CR
[ a b c] CR})
4 (let [[a b c d] liga]
{ [CR CR CR d] (str a "_" b "_" c "_" d)
[CR CR c d] CR
[CR b c d] CR
[ a b c d] CR})))
(defn any? [p & colls]
(if colls
(let [[coll & cs] colls]
(some #(apply any? (partial p %) cs) coll))
(p)))
(defn conflicts? [r1 r2]
(when (.startsWith (first r2) "CR.") ;; we accept that higher-len ligatures can override lower-length
;; but once replacement has started (first glyph in rule is CR.*)
;; there should be no possibility for conflits
(let [l1 (count r1)
l2 (count r2)
prefix1 (subvec r1 0 l2)]
(= r2 prefix1))))
(def all-rules
(reduce
(fn [generated liga]
(merge generated
;; looking for smallest i that does not conflict
;; with any of previous rules
(some (fn [i]
(let [CR (str "CR." (String/format "%02d" (to-array [i])))
rs (liga->rules liga CR)]
(when-not (any? conflicts? (keys generated) (keys rs))
rs)))
(range))))
{}
(->> ligas (sort-by count) reverse)))
(defn priority-fn [[from to]]
[;; first compare how many CRs are there (more is better)
(- (count (filter #(re-matches #"CR\.\d+" %) from)))
;; then overal length (more is better)
(- (count from))
;; then alphabetical sort with coercing each vector to the same length
(into from (repeat (- 4 (count from)) "z"))])
(def table (->> all-rules
(sort-by priority-fn)))
(defn rule->str [[from to]]
(loop [res "sub"
seen-non-empty? false
tokens from]
(if-let [token (first tokens)]
(let [class? (.startsWith token "@")
CR? (.startsWith token "CR.")
escaped-token (cond
class? token
CR? (str "\\" token)
seen-non-empty? (str "\\" token)
:else (str "\\" token "'"))]
(recur (str res " " escaped-token) (not CR?) (next tokens)))
(str res " by \\" to ";"))))
(println "feature calt {")
(println " " (->> table (map rule->str) (str/join "\n ")))
(println "} calt;\n")