LIG -> *.spacer

This commit is contained in:
Nikita Prokopov 2020-03-24 00:37:50 +01:00
parent 553fce5740
commit 84f8fa6b9c
10 changed files with 638 additions and 94 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,11 @@
;; clj -m regen-calt
(ns regen-calt
(ns fira-code.calt
(:require
[clojure.string :as str]
[glyphs :as glyphs]))
[clojure.string :as str]
[fira-code.coll :as coll]
[fira-code.glyphs :as glyphs]
[fira-code.time :as time]
[flatland.ordered.map :refer [ordered-map]]))
;; No ligature should follow those sequences
(def ignore-prefixes
@ -142,8 +144,8 @@
" ignore sub 1' 2 2;\n"))
(gen-ignore-prefixes liga)
(get ignores liga)
" sub LIG 2' by 1_2.liga;\n"
" sub 1' 2 by LIG;\n"
" sub 1.spacer 2' by 1_2.liga;\n"
" sub 1' 2 by 1.spacer;\n"
"} 1_2;")
#"\d" {"1" a "2" b}))
3 (let [[a b c] liga]
@ -154,9 +156,9 @@
" ignore sub 1' 2 3 3;\n"))
(gen-ignore-prefixes liga)
(get ignores liga)
" sub LIG LIG 3' by 1_2_3.liga;\n"
" sub LIG 2' 3 by LIG;\n"
" sub 1' 2 3 by LIG;\n"
" sub 1.spacer 2.spacer 3' by 1_2_3.liga;\n"
" sub 1.spacer 2' 3 by 2.spacer;\n"
" sub 1' 2 3 by 1.spacer;\n"
"} 1_2_3;")
#"\d" {"1" a "2" b "3" c}))
4 (let [[a b c d] liga]
@ -167,24 +169,13 @@
" ignore sub 1' 2 3 4 4;\n"))
(gen-ignore-prefixes liga)
(get ignores liga)
" sub LIG LIG LIG 4' by 1_2_3_4.liga;\n"
" sub LIG LIG 3' 4 by LIG;\n"
" sub LIG 2' 3 4 by LIG;\n"
" sub 1' 2 3 4 by LIG;\n"
" sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga;\n"
" sub 1.spacer 2.spacer 3' 4 by 3.spacer;\n"
" sub 1.spacer 2' 3 4 by 2.spacer;\n"
" sub 1' 2 3 4 by 1.spacer;\n"
"} 1_2_3_4;")
#"\d" {"1" a "2" b "3" c "4" d}))))
(defn index-of [pred xs]
(reduce (fn [i x] (if (pred x) (reduced i) (inc i))) 0 xs))
(defn replace-calt [font calt]
(let [features (:features font)
idx (index-of #(= "calt" (:name %)) features)
code (get-in features [idx :code])
code' (str/replace code
#"### start of generated calt\n[^#]+\n### end of generated calt\n"
(str "### start of generated calt\n" calt "\n### end of generated calt\n"))]
(assoc-in font [:features idx :code] code')))
(defn compare-ligas [l1 l2]
(cond
@ -192,24 +183,26 @@
(< (count l1) (count l2)) 1
:else (compare l1 l2)))
(defn -main [& args]
(let [path (or (first args) "FiraCode.glyphs")
font (glyphs/load path)
ligas (for [g (:glyphs font)
:let [name (:glyphname g)]
:when (str/ends-with? name ".liga")
:when (not= "0" (:export g))
:let [[_ liga] (re-matches #"([A-Za-z_]+)\.liga" name)]]
(str/split liga #"_")) ;; [ ["dash" "greater" "greater"] ... ]
calt (->> ligas (remove manual?) (sort compare-ligas) (map liga->rule) (str/join "\n\n"))
font' (replace-calt font calt)]
(glyphs/save! path font')
(defn replace-calt [font ligas]
(let [ligas' (->> ligas
(remove manual?)
(sort compare-ligas))
calt (->> ligas'
(map liga->rule)
(str/join "\n\n"))
glyphs (map #(str (str/join "_" %) ".liga") ligas')
counts (coll/group-by-to count count ligas')]
(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 " generated calt:"
(str/join " " glyphs)
(str
"(" (get counts 2) " pairs, "
(get counts 3) " triples, "
(get counts 4) " quadruples, "
(count ligas') " total)"))
(glyphs/update-code font :features "calt"
#(str/replace %
#"### start of generated calt\n[^#]+\n### end of generated calt\n"
(str "### start of generated calt\n" calt "\n### end of generated calt\n")))))

View File

@ -0,0 +1,15 @@
(ns fira-code.coll)
(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))
(defn group-by-to [key-fn value-fn xs]
(reduce-kv
(fn [m k vs]
(assoc m k (value-fn vs)))
{}
(group-by key-fn xs)))

View File

@ -1,9 +1,10 @@
(ns glyphs
(ns fira-code.glyphs
(:refer-clojure :exclude [load])
(:require
[clojure.java.io :as io]
[clojure.string :as str]
[fipp.edn :as fipp]
[fira-code.coll :as coll]
[flatland.ordered.map :refer [ordered-map]]))
(def ^:dynamic *str)
@ -137,11 +138,11 @@
; (-> (slurp "FiraCode.glyphs") parse serialize (->> (spit "FiraCode_saved.glyphs")))
(defn load [path]
(println "Parsing" path "...")
(println (str "Parsing '" path "'..."))
(parse (slurp path)))
(defn save! [path font]
(println "Saving" path "...")
(println (str "Saving '" path "'..."))
(spit path (serialize font)))
(defn -main [& args]
@ -150,8 +151,16 @@
(binding [*out* os]
(fipp/pprint font {:width 200})))))
(def weights {:Regular "UUID0"
:Bold "BF448B58-7A35-489E-A1C9-12628F60690C"})
(defn update-code [font key name f & args]
(let [idx (coll/index-of #(= (:name %) name) (get font key))]
(apply update-in font [key idx :code] f args)))
(def weights
{:Light "B67F0F2D-EC95-4CB8-966E-23AE86958A69"
:Regular "UUID0"
:Bold "4B7A3BAF-EAD8-4024-9BEA-BB1DE86CFCFA"})
(defn layer [l]
{ :id (case (:layerId l)

View File

@ -0,0 +1,27 @@
(ns fira-code.main
(:require
[clojure.string :as str]
[fira-code.calt :as calt]
[fira-code.coll :as coll]
[fira-code.glyphs :as glyphs]
[fira-code.not-space :as not-space]
[fira-code.spacers :as spacers]
[fira-code.time :as time]
[flatland.ordered.map :refer [ordered-map]]))
(defn -main [& args]
(let [path (or (first args) "FiraCode.glyphs")
font (glyphs/load path)
ligas (for [g (:glyphs font)
:let [name (:glyphname g)]
:when (str/ends-with? name ".liga")
:when (not= "0" (:export g))
:let [[_ liga] (re-matches #"([A-Za-z_]+)\.liga" name)]]
(str/split liga #"_")) ;; [ ["dash" "greater" "greater"] ... ]
font' (-> font
(calt/replace-calt ligas)
(spacers/add-spacers ligas)
(not-space/regen-not-space))]
(glyphs/save! path font')
(println)))

View File

@ -0,0 +1,14 @@
(ns fira-code.not-space
(:require
[clojure.string :as str]
[fira-code.glyphs :as glyphs]))
(defn regen-not-space [font]
(let [not-spaces (->> (:glyphs font)
(remove #(re-find #"^\.|space$|space\." (:glyphname %)))
(remove #(= "0" (:export %)))
(map :glyphname)
(sort))]
(println " regenerated NotSpace:" (count not-spaces) "glyphs")
(glyphs/update-code font :classes "NotSpace" (constantly (str/join " " not-spaces)))))

View File

@ -0,0 +1,31 @@
(ns fira-code.spacers
(:require
[clojure.string :as str]
[fira-code.glyphs :as glyphs]
[fira-code.time :as time]
[flatland.ordered.map :refer [ordered-map]]))
(defn spacer [name]
(ordered-map
:color 3,
:glyphname name,
:lastChange (time/now-str),
:layers
[(ordered-map :layerId (:Light glyphs/weights), :width 1200)
(ordered-map :layerId (:Bold glyphs/weights), :width 1200)]))
(defn add-spacers [font ligas]
(let [needed (->> (into #{} cat ligas)
(map #(str % ".spacer")))
existing (->> (:glyphs font)
(map :glyphname)
(filter #(str/ends-with? % ".spacer")))
new (->> (remove (set existing) needed)
(sort-by str/lower-case))]
(if-not (empty? new)
(do
(println " added glyphs: " (str/join " " new))
(update font :glyphs #(into % (map spacer new))))
font)))

View File

@ -0,0 +1,13 @@
(ns fira-code.time
(:import
[java.time LocalDateTime ZoneId]
[java.time.format DateTimeFormatter]))
(def ^ZoneId UTC (ZoneId/of "UTC"))
(defn now-str []
(.format
(DateTimeFormatter/ofPattern "yyyy-MM-dd HH:mm:ss +0000")
(LocalDateTime/now UTC)))

View File

@ -1,26 +0,0 @@
;; clj -m regen-classes
(ns regen-classes
(:require
[clojure.string :as str]
[glyphs :as glyphs]
[flatland.ordered.map :refer [ordered-map]]))
(defn -main [& args]
(let [path (or (first args) "FiraCode.glyphs")
font (glyphs/load path)
not-spaces (->> (:glyphs font)
(remove #(re-find #"^\.|space$|space\." (:glyphname %)))
(remove #(= "0" (:export %))))
_ (println "Generating class:NotSpace with" (count not-spaces) "glyphs")
class (ordered-map
:code (str/join " " (map :glyphname not-spaces))
:name "NotSpace")
classes (->> (:classes font)
(remove #(= "NotSpace" (:name %)))
(cons class))
font' (assoc font :classes classes)
_ (glyphs/save! path font')
_ (println)]))
; (-main)

3
script/update_glyphs Executable file
View File

@ -0,0 +1,3 @@
#!/bin/zsh -euo pipefail
clojure -m fira-code.main