Skip to content

Commit

Permalink
- Removed !!! ??? ;;; &&& ||| =~ (closes tonsky#167) `~~~…
Browse files Browse the repository at this point in the history
…` `%%%`

- New `calt` code disables ligatures on long sequences, e.g. `!!!!`,
  `>>>>`, etc (closes tonsky#49, closes tonsky#110, closes tonsky#176)
  • Loading branch information
tonsky committed Jul 17, 2016
1 parent afb9f6b commit 4903955
Show file tree
Hide file tree
Showing 10 changed files with 6,037 additions and 9,611 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.zip
Fira Code_liga.glyphs
FiraCode_liga.glyphs
FiraCode_mess.glyphs
Binary file modified FiraCode-Bold.otf
Binary file not shown.
Binary file modified FiraCode-Light.otf
Binary file not shown.
Binary file modified FiraCode-Medium.otf
Binary file not shown.
Binary file modified FiraCode-Regular.otf
Binary file not shown.
Binary file modified FiraCode-Retina.otf
Binary file not shown.
15,526 changes: 6,001 additions & 9,525 deletions FiraCode.glyphs

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,16 @@ Other monospaced fonts with ligatures:

### Changelog

#### Work in progress

- Removed `!!!` `???` `;;;` `&&&` `|||` `=~` (#167) `~~~` `%%%`
- New safer `calt` code that doesn’t apply ligatures to long sequences of chars, e.g. `!!!!`, `>>>>`, etc (#49, #110, #176)

#### 1.102

- Support for IntelliJ-based IDEs ([instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions))
- Turned on autohinting


#### 1.101

- Added Light weight
Expand Down
113 changes: 29 additions & 84 deletions gen_calt.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,105 +31,50 @@
; ["asterisk" "asterisk" "asterisk"]])


(defn liga->rules
(defn liga->rule
"[f f i] => { [CR CR i] f_f_i.liga
[CR f i] CR
[ f f i] CR }"
[liga CR]
[liga]
(case (count liga)
2 (let [[a b] liga]
{ [CR b] (str a "_" b ".liga")
[ a b] CR})
(str/replace
(str " lookup 1_2 {\n"
" ignore sub 1 1' 2;\n"
" ignore sub 1' 2 2;\n"
" sub CR 2' by 1_2.liga;\n"
" sub 1' 2 by CR;\n"
" } 1_2;")
#"\d" {"1" a "2" b}))
3 (let [[a b c] liga]
{ [CR CR c] (str a "_" b "_" c ".liga")
[CR b c] CR
[ a b c] CR})
(str/replace
(str " lookup 1_2_3 {\n"
" ignore sub 1 1' 2 3;\n"
" ignore sub 1' 2 3 3;\n"
" sub CR CR 3' by 1_2_3.liga;\n"
" sub CR 2' 3 by CR;\n"
" sub 1' 2 3 by CR;\n"
" } 1_2_3;")
#"\d" {"1" a "2" b "3" c}))
4 (let [[a b c d] liga]
{ [CR CR CR d] (str a "_" b "_" c "_" d ".liga")
[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)]
; (println (keys generated) (keys rs))
(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 ";"))))

(str/replace
(str " lookup 1_2_3_4 {\n"
" sub CR CR CR 4' by 1_2_3_4.liga;\n"
" sub CR CR 3' 4 by CR;\n"
" sub CR 2' 3 4 by CR;\n"
" sub 1' 2 3 4 by CR;\n"
" } 1_2_3_4;")
#"\d" {"1" a "2" b "3" c "4" d}))))


(println "feature calt {")
(println " " (->> table (map rule->str) (str/join "\n ")))
(println (->> ligas (sort-by count) (reverse) (map liga->rule) (str/join "\n\n")))
(println "}\n")



(apply println "Placeholders:\n " (->> table (mapcat first) (filter #(.startsWith % "CR.")) distinct sort))
(println)


(println "Total ligatures count:" (count ligas))
(println " " (->> ligas
(group-by count)
(sort-by first)
(map (fn [[k v]] (str (count v) (case k 2 " pairs", 3 " triples", 4 " quadruples"))))
(str/join ", ")))
(println)

(println "Total rules count:" (count table))
Binary file modified showcases/Fira Code Showcases.sketch
Binary file not shown.

0 comments on commit 4903955

Please sign in to comment.