From ace859529f204020e75d9a4e336ecde62a968ef4 Mon Sep 17 00:00:00 2001 From: Nikita Prokopov Date: Wed, 13 May 2020 22:52:31 +0200 Subject: [PATCH] Extracted other features and classes into separate files, fixed few ligatures conflicts with arrows --- FiraCode.glyphs | 13 ++++---- classes/ClosingBracket.fea | 1 + classes/Digit.fea | 13 ++++++++ classes/DigitTosf.fea | 12 ++++++++ classes/HexDigit.fea | 1 + classes/OpeningBracket.fea | 1 + classes/Tall.fea | 1 + clojure/fira_code/calt.clj | 29 ++++++++++-------- clojure/fira_code/classes.clj | 18 +++++++++++ clojure/fira_code/coll.clj | 5 ++-- clojure/fira_code/features.clj | 35 ++++++++++++++++++---- clojure/fira_code/files.clj | 12 ++++++++ clojure/fira_code/glyphs.clj | 31 +++++++++++++++++++ clojure/fira_code/main.clj | 4 ++- features/{ => calt}/arrows.fea | 0 features/{ => calt}/case.fea | 0 features/{ => calt}/conj_disj.fea | 0 features/{ => calt}/cross.fea | 0 features/{ => calt}/fi_fl.fea | 0 features/{ => calt}/greek.fea | 0 features/{ => calt}/less_tilde_greater.fea | 0 features/onum.fea | 12 ++++++++ features/ss01.fea | 3 ++ features/ss02.fea | 4 +++ features/ss03.fea | 8 +++++ features/ss04.fea | 7 +++++ features/ss05.fea | 5 ++++ features/ss06.fea | 7 +++++ features/ss07.fea | 15 ++++++++++ showcases/v3/showcases.txt | 4 +-- 30 files changed, 211 insertions(+), 30 deletions(-) create mode 100644 classes/ClosingBracket.fea create mode 100644 classes/Digit.fea create mode 100644 classes/DigitTosf.fea create mode 100644 classes/HexDigit.fea create mode 100644 classes/OpeningBracket.fea create mode 100644 classes/Tall.fea create mode 100644 clojure/fira_code/classes.clj create mode 100644 clojure/fira_code/files.clj rename features/{ => calt}/arrows.fea (100%) rename features/{ => calt}/case.fea (100%) rename features/{ => calt}/conj_disj.fea (100%) rename features/{ => calt}/cross.fea (100%) rename features/{ => calt}/fi_fl.fea (100%) rename features/{ => calt}/greek.fea (100%) rename features/{ => calt}/less_tilde_greater.fea (100%) create mode 100644 features/onum.fea create mode 100644 features/ss01.fea create mode 100644 features/ss02.fea create mode 100644 features/ss03.fea create mode 100644 features/ss04.fea create mode 100644 features/ss05.fea create mode 100644 features/ss06.fea create mode 100644 features/ss07.fea diff --git a/FiraCode.glyphs b/FiraCode.glyphs index fa48010..8d2a201 100644 --- a/FiraCode.glyphs +++ b/FiraCode.glyphs @@ -4,7 +4,7 @@ DisplayStrings = ( "/greater_start.arw ->-/greater_end.arw \012/greater_start.darw/equal_end.darw/greater_middle.darw/equal_end.darw/greater_end.darw \012>>->>-/space/greater_greater_end.arw \012/space/greater_greater_start.darw/equal_end.darw/space/greater_greater_middle.darw/equal_end.darw/space/greater_greater_end.darw \012<-<-<\012/less_start.darw/equal_end.darw/less_middle.darw/equal_end.darw/less_end.darw \012<<-<<-<<\012/space/less_less_start.darw/equal_end.darw/space/less_less_middle.darw/equal_end.darw/space/less_less_end.darw \012|-|-|\012/bar_start.darw/equal_end.darw/bar_middle.darw/equal_end.darw/bar_end.darw \012||-||-||\012/space/bar_bar_start.darw/equal_end.darw/space/bar_bar_middle.darw/equal_end.darw/space/bar_bar_end.darw", "<============================================<<\012=====/space ====/space ===>>/space ====|/space ===||\012<====/space <===/space <==>>/space <===|/space <==||/space ==<==\012<<===/space <<==/space <<=>>/space <<==|/space <<=||/space =<<=\012>====/space >=====<===>/space >==>>/space >===|/space >==||/space ==>==\012>>===/space >>==>=<>==>/space >>=>>/space >>==|/space >>=||/space =>>=\012|====/space |===/space |==>>/space |===|/space |==||/space ==|==\012||===/space ||==/space ||=>>/space ||==|/space ||=||/space =||=\012|==<==<<==>>==>==|==||==|\012.=/space ..=/space :=/space ::=/space !=/space !==/space ?=/space #=/space \012=:=/space =!=/space =/space ==/space ===/space =//=>=/space <=/space ^=\012>==/space <||>\012", "<---------------------<<\012-----/space ----/space --->>/space ----|/space ---||\012<----/space <---/space <-->>/space <---|/space <--||/space --<--\012<<---/space <<--/space <<->>/space <<--|/space <<-||/space -<<-\012>----/space >-----<--->/space >-->>/space >---|/space >--||/space -->--\012>>---/space >>-->-<>-->/space >>->>/space >>--|/space >>-||/space ->>-\012|----/space |---/space |-->>/space |---|/space |--||/space --|--\012||---/space ||--/space ||->>/space ||--|/space ||-||/space -||-\012|--<--<<-->>-->--|--||--|\012-/space --/space ---/space |>/space <|/space ||>/space <||/space ;; #346 <--> <---> |--| |---| - ["hyphen" "hyphen"] (str " ignore sub [bracketleft less greater bar] hyphen' hyphen;\n" " ignore sub hyphen' hyphen [bracketright less greater bar];\n") @@ -144,8 +142,6 @@ ["less" "asterisk" "greater"] ["less" "plus" "greater"] ["less" "dollar" "greater"] - ;; #795 - ["f" "l"] ["F" "l"] ["T" "l"] }) @@ -245,6 +241,15 @@ glyphs (map #(str (str/join "_" %) ".liga") ligas') counts (coll/group-by-to count count ligas')] + (when-some [unused (not-empty (reduce dissoc ignores ligas'))] + (println " WARN Unused ignores" (str/join " " (keys unused)))) + + (when-some [unused (not-empty (reduce disj skip-ignores? ligas'))] + (println " WARN Unused skip-ignores?" (str/join " " unused))) + + (when-some [unused (not-empty (reduce disj manual? ligas))] + (println " WARN Unused manual?" (str/join " " unused))) + (println " generated calt:" ; (str/join " " glyphs) (str diff --git a/clojure/fira_code/classes.clj b/clojure/fira_code/classes.clj new file mode 100644 index 0000000..99ea1df --- /dev/null +++ b/clojure/fira_code/classes.clj @@ -0,0 +1,18 @@ +(ns fira-code.classes + (:require + [clojure.java.io :as io] + [clojure.string :as str] + [fira-code.glyphs :as glyphs] + [fira-code.files :as files])) + + +(defn fill-class [font file] + (let [[_ name] (re-matches #"([^.]+)\.fea" (.getName file)) + code (slurp file) + class {:code (str/trim code) + :name name}] + (glyphs/set-class font name class))) + + +(defn fill-all [font] + (reduce fill-class font (files/find "classes" #"classes/[^/]+\.fea"))) diff --git a/clojure/fira_code/coll.clj b/clojure/fira_code/coll.clj index 30d41c4..e474e32 100644 --- a/clojure/fira_code/coll.clj +++ b/clojure/fira_code/coll.clj @@ -3,8 +3,9 @@ (defn index-of [pred xs] (let [res (reduce (fn [i x] (if (pred x) (reduced i) (inc i))) 0 xs)] - (assert (< res (count xs)) "Nothing found") - res)) + (if (>= res (count xs)) + -1 + res))) (defn group-by-to [key-fn value-fn xs] diff --git a/clojure/fira_code/features.clj b/clojure/fira_code/features.clj index 497a75a..982ee6e 100644 --- a/clojure/fira_code/features.clj +++ b/clojure/fira_code/features.clj @@ -2,15 +2,38 @@ (:require [clojure.java.io :as io] [clojure.string :as str] - [fira-code.glyphs :as glyphs])) + [fira-code.glyphs :as glyphs] + [fira-code.files :as files])) -(defn append-features [font] - (let [features (->> (file-seq (io/file "features")) - (filter #(str/ends-with? (.getName %) ".fea")) - (sort-by #(.getName %)) +(defn append-calt [font] + (let [features (->> (files/find "features/calt" #"features/calt/[^/]+\.fea") (map slurp) (map str/trim) (str/join "\n\n"))] + (println " appending to feature calt" (glyphs/lines features) "lines") (glyphs/update-code font :features "calt" - #(str % "\n\n" features)))) \ No newline at end of file + #(str % "\n\n" features)))) + + +(defn fill-feature [font file] + (let [[_ name] (re-matches #"([^.]+)\.fea" (.getName file)) + code (slurp file) + [_ notes code'] (re-matches #"(?s)#([^\n]+)\n(.*)" code) + feature (if notes + {:code (str/trim code') + :name name + :notes (str/trim notes)} + {:code (str/trim code) + :name name})] + (glyphs/set-feature font name feature))) + + +(defn fill-features [font] + (reduce fill-feature font (files/find "features" #"features/[^/]+\.fea"))) + + +(defn fill-all [font] + (-> font + (append-calt) + (fill-features))) \ No newline at end of file diff --git a/clojure/fira_code/files.clj b/clojure/fira_code/files.clj new file mode 100644 index 0000000..e36e0cb --- /dev/null +++ b/clojure/fira_code/files.clj @@ -0,0 +1,12 @@ +(ns fira-code.files + (:refer-clojure :exclude [find]) + (:require + [clojure.java.io :as io] + [clojure.string :as str])) + + +(defn find [path re] + (->> (file-seq (io/file path)) + (next) ;; skip directory itself + (filter #(re-matches re (.getPath %))) + (sort-by #(.getPath %)))) \ No newline at end of file diff --git a/clojure/fira_code/glyphs.clj b/clojure/fira_code/glyphs.clj index fbfa90d..9c2e649 100755 --- a/clojure/fira_code/glyphs.clj +++ b/clojure/fira_code/glyphs.clj @@ -154,9 +154,40 @@ (defn update-code [font key name f & args] (let [idx (coll/index-of #(= (:name %) name) (get font key))] + (assert (>= idx 0) (str "Can’t find " key "[name=\"" name "\"], got " (str/join ", " (map :name (get font key))))) (apply update-in font [key idx :code] f args))) +(defn lines [s] + (inc (count (re-seq #"\n" s)))) + + +(defn words [s] + (count (re-seq #"[^\s]+" s))) + + +(defn set-feature [font name feature] + (let [idx (coll/index-of #(= (:name %) name) (:features font))] + (if (pos? idx) + (do + (println " replacing feature" name "with" (lines (:code feature)) "lines") + (assoc-in font [:features idx] feature)) + (do + (println " appending to feature" name (lines (:code feature)) "lines") + (update font :features conj feature))))) + + +(defn set-class [font name class] + (let [idx (coll/index-of #(= (:name %) name) (:classes font))] + (if (pos? idx) + (do + (println " replacing class" name "with" (words (:code class)) "entries") + (assoc-in font [:classes idx] class)) + (do + (println " appending to class" name (words (:code class)) "entries") + (update font :classes conj class))))) + + (def weights {:Light "B67F0F2D-EC95-4CB8-966E-23AE86958A69" :Regular "UUID0" diff --git a/clojure/fira_code/main.clj b/clojure/fira_code/main.clj index ac905c6..0273c78 100644 --- a/clojure/fira_code/main.clj +++ b/clojure/fira_code/main.clj @@ -4,6 +4,7 @@ [fira-code.calt :as calt] [fira-code.coll :as coll] [fira-code.checks :as checks] + [fira-code.classes :as classes] [fira-code.features :as features] [fira-code.glyphs :as glyphs] [fira-code.not-space :as not-space] @@ -23,7 +24,8 @@ (str/split liga #"_")) ;; [ ["dash" "greater" "greater"] ... ] font' (-> font (calt/replace-calt ligas) - (features/append-features) + (classes/fill-all) + (features/fill-all) (spacers/add-spacers ligas) (not-space/regen-not-space) (checks/widths))] diff --git a/features/arrows.fea b/features/calt/arrows.fea similarity index 100% rename from features/arrows.fea rename to features/calt/arrows.fea diff --git a/features/case.fea b/features/calt/case.fea similarity index 100% rename from features/case.fea rename to features/calt/case.fea diff --git a/features/conj_disj.fea b/features/calt/conj_disj.fea similarity index 100% rename from features/conj_disj.fea rename to features/calt/conj_disj.fea diff --git a/features/cross.fea b/features/calt/cross.fea similarity index 100% rename from features/cross.fea rename to features/calt/cross.fea diff --git a/features/fi_fl.fea b/features/calt/fi_fl.fea similarity index 100% rename from features/fi_fl.fea rename to features/calt/fi_fl.fea diff --git a/features/greek.fea b/features/calt/greek.fea similarity index 100% rename from features/greek.fea rename to features/calt/greek.fea diff --git a/features/less_tilde_greater.fea b/features/calt/less_tilde_greater.fea similarity index 100% rename from features/less_tilde_greater.fea rename to features/calt/less_tilde_greater.fea diff --git a/features/onum.fea b/features/onum.fea new file mode 100644 index 0000000..1cfd4e7 --- /dev/null +++ b/features/onum.fea @@ -0,0 +1,12 @@ +sub zero by zero.tosf; +sub zero.zero by zero.zero.tosf; +sub one by one.tosf; +sub two by two.tosf; +sub three by three.tosf; +sub four by four.tosf; +sub five by five.tosf; +sub six by six.tosf; +sub seven by seven.tosf; +sub eight by eight.tosf; +sub nine by nine.tosf; +sub x.multiply by x.multiply.tosf; \ No newline at end of file diff --git a/features/ss01.fea b/features/ss01.fea new file mode 100644 index 0000000..70223d5 --- /dev/null +++ b/features/ss01.fea @@ -0,0 +1,3 @@ +# Name: Sans serif lowercase r + +sub r by r.ss01; \ No newline at end of file diff --git a/features/ss02.fea b/features/ss02.fea new file mode 100644 index 0000000..b971279 --- /dev/null +++ b/features/ss02.fea @@ -0,0 +1,4 @@ +# Name: Less Than/Greater Than with horizontal bar + +sub greater_equal.liga by greater_equal.ss02; +sub less_equal.liga by less_equal.ss02; \ No newline at end of file diff --git a/features/ss03.fea b/features/ss03.fea new file mode 100644 index 0000000..525381d --- /dev/null +++ b/features/ss03.fea @@ -0,0 +1,8 @@ +# Name: Traditional Ampersand + +sub ampersand by ampersand.ss03; + +sub ampersand_ampersand.liga by ampersand.ss03; +sub ampersand.spacer' ampersand.ss03 by ampersand.before.ss03; + +sub [ampersand ampersand.ss03]' [ampersand ampersand.ss03] by ampersand.before.ss03; \ No newline at end of file diff --git a/features/ss04.fea b/features/ss04.fea new file mode 100644 index 0000000..f6f90c8 --- /dev/null +++ b/features/ss04.fea @@ -0,0 +1,7 @@ +# Name: Lightweight Dollar Sign + +sub dollar by dollar.ss04; + +sub dollar_greater.liga by dollar_greater.liga.ss04; +sub less_dollar_greater.liga by less_dollar_greater.liga.ss04; +sub less_dollar.liga by less_dollar.liga.ss04; \ No newline at end of file diff --git a/features/ss05.fea b/features/ss05.fea new file mode 100644 index 0000000..a4b8b5c --- /dev/null +++ b/features/ss05.fea @@ -0,0 +1,5 @@ +# Name: Traditional At sign + +sub at by at.ss05; +sub asciitilde.spacer' asciitilde_at.liga by asciitilde; +sub asciitilde asciitilde_at.liga' by at.ss05; \ No newline at end of file diff --git a/features/ss06.fea b/features/ss06.fea new file mode 100644 index 0000000..d092cd9 --- /dev/null +++ b/features/ss06.fea @@ -0,0 +1,7 @@ +# Name: Thin backslash + +sub backslash' by backslash.ss06; + +lookup backslash_thin { + sub backslash.ss06 backslash.ss06' by backslash.thick.ss06; +} backslash_thin; \ No newline at end of file diff --git a/features/ss07.fea b/features/ss07.fea new file mode 100644 index 0000000..8721791 --- /dev/null +++ b/features/ss07.fea @@ -0,0 +1,15 @@ +# Name: Regex matching operator + +lookup equal_asciitilde { + ignore sub equal equal' asciitilde; + ignore sub equal' asciitilde asciitilde; + sub equal.spacer asciitilde' by equal_asciitilde.ss07; + sub equal' asciitilde by equal.spacer; +} equal_asciitilde; + +lookup exclam_asciitilde { + ignore sub exclam exclam' asciitilde; + ignore sub exclam' asciitilde asciitilde; + sub exclam.spacer asciitilde' by exclam_asciitilde.ss07; + sub exclam' asciitilde by exclam.spacer; +} exclam_asciitilde; \ No newline at end of file diff --git a/showcases/v3/showcases.txt b/showcases/v3/showcases.txt index 398c3c8..855ff7c 100644 --- a/showcases/v3/showcases.txt +++ b/showcases/v3/showcases.txt @@ -114,5 +114,5 @@ r 0 123456789 & && $ <$ <$> $> @ <= >= ||=== ||==< ||=<< ||==> ||=>> ||==| ||=|| =||= |==<==<<==>>==>==|==||==| .= ..= := ::= != !== ?= #= /= /== -=:= =!= = == === =/= >= <= ^= ->=< :>= <||> \ No newline at end of file +=:= =!= = == === =/= >= <= ^= <=< >=> +>=< =< :>= <||> <<<-<<< <<<=<<< >>>->>> >>>=>>> \ No newline at end of file