generate-mods.clj

Pinchord · pinchord.git · Tickets · Changelog

Branches > serial-mods > dd1adf7 > files / generate-mods.clj

(def symbol-names
  {"á" "aacute"
   "â" "acircumflex"
   "´" "acute"
   "ä" "adiaeresis"
   "æ" "ae"
   "à" "agrave"
   "&" "ampersand"
   "'" "apostrophe"
   "å" "aring"
   "^" "asciicircum"
   "~" "asciitilde"
   "*" "asterisk"
   "@" "at"
   "ã" "atilde"
   "\\" "backslash"
   "|" "bar"
   "\\{" "braceleft"
   "\\}" "braceright"
   "[" "bracketleft"
   "]" "bracketright"
   "¦" "brokenbar"
   "ç" "ccedilla"
   "¸" "cedilla"
   "¢" "cent"
   ":" "colon"
   "{^ ^}" "space"
   "," "comma"
   "©" "copyright"
   "¤" "currency"
   "°" "degree"
   "¨" "diaeresis"
   "÷" "division"
   "$" "dollar"
   "é" "eacute"
   "ê" "ecircumflex"
   "ë" "ediaeresis"
   "è" "egrave"
   "=" "equal"
   "ð" "eth"
   "!" "exclam"
   "¡" "exclamdown"
   "`" "grave"
   ">" "greater"
   "«" "guillemotleft"
   "»" "guillemotright"
   "­" "hyphen"
   "í" "iacute"
   "î" "icircumflex"
   "ï" "idiaeresis"
   "ì" "igrave"
   "<" "less"
   "¯" "macron"
   "º" "masculine"
   "-" "minus"
   "µ" "mu"
   "×" "multiply"
   "¬" "notsign"
   "ñ" "ntilde"
   "#" "numbersign"
   "ó" "oacute"
   "ô" "ocircumflex"
   "ö" "odiaeresis"
   "ò" "ograve"
   "½" "onehalf"
   "¼" "onequarter"
   "¹" "onesuperior"
   "Ø" "ooblique"
   "ª" "ordfeminine"
   "ø" "oslash"
   "õ" "otilde"
   "¶" "paragraph"
   "(" "parenleft"
   ")" "parenright"
   "%" "percent"
   "." "period"
   "·" "periodcentered"
   "+" "plus"
   "±" "plusminus"
   "?" "question"
   "¿" "questiondown"
   "\"" "quotedbl"
   "®" "registered"
   "\r" "return"
   "§" "section"
   ";" "semicolon"
   "/" "slash"
   "ß" "ssharp"
   "£" "sterling"
   "\t" "tab"
   "þ" "thorn"
   "¾" "threequarters"
   "³" "threesuperior"
   "²" "twosuperior"
   "ú" "uacute"
   "û" "ucircumflex"
   "ü" "udiaeresis"
   "ù" "ugrave"
   "_" "underscore"
   "ý" "yacute"
   "ÿ" "ydiaeresis"
   "¥" "yen"})

(defn symbol-name [x]
  (or (symbol-names x) (throw (ex-info (str "No such symbol! " x) {:symbol x}))))

(def symbols
  {:starter "TSHR"
   :chords {"P" "."
            "RP" "/"
            "RPS" "^"
            "LRPKS" "&"
            "LRPKFS" "@"
            "K" ","
            "PS" "\\"
            "FS" ":" "^FS" ";"
            "RPKF" "$"
            "LRFS" "#"
            "L" "'" "^L" "`"
            "PK" "|"
            "LR" "!"
            "F" "*"
            "LPKF" "¥"
            "LP" "\""
            "PKFS" "="
            "LPK" "?"
            "RPKS" "+"
            ; Unfortunately, Plover does not see the vision
            ; Will have to implement these separately
            #_["LRPKF" "€" "^LRPKF" "£"]
            "PF" "-"
            "KS" "_"
            "LRPK" "%"
            "LPKS" "~"
            "LRK" "("
            "LK" "<"
            "LRP" "[" "^LRP" "\\{"
            "" "{^ ^}"
            "RPK" ")"
            "KF" ">"
            "PFS" "]"
            "^PFS" "\\}"}

   :shortcuts {"RK" "backspace" "^RK" "delete"
               "LPF" "escape"}
   :mod-shortcuts {"RF" {:no-mods "{^}\n"
                         :with-mods "return"}
                   "LS" {:no-mods "{^}\t"
                         :with-mods "tab"}}})

(defn apply-mods [mod-set chord _]
  (str "{#"
       (reduce (fn [acc mod]
                 (str mod "(" acc ")"))
               chord mod-set)
       "}"))

(def vowel-chords
  {"A"    ["control"]
   "O"    ["shift"]
   "I"    ["super"]
   "U"    ["alt"]
   "AO"   ["control" "shift"]
   "AI"   ["control" "super"]
   "AU"   ["control" "alt"]
   "OI"   ["shift" "super"]
   "OU"   ["shift" "alt"]
   "IU"   ["super" "alt"]
   "AOI"  ["control" "shift" "super"]
   "AOU"  ["control" "shift" "alt"]
   "AIU"  ["control" "super" "alt"]
   "OIU"  ["shift" "super" "alt"]
   "AOIU" ["control" "shift" "super" "alt"]})

(def no-mods {"-" []})
(def all-mods (merge vowel-chords no-mods))

(def repetitions
  {"" 1
   "*" 2
   "T" 3
   "T*" 4})
(def no-repetition
  {"" 1})

(def always-attach {"" "{^}"
                    "+" "{^}"})
(def never-attach {"" ""
                   "+" ""})
(def attach {"" "{}"
             "+" "{^}"})
(def attach-and-capitalize
  (assoc attach
         "#" "{}{-|}"
         "#+" "{^}{-|}"))

(defn flatten-map
  "Flattens a nested sequence of key value pairs into a map."
  [xs]
  (apply hash-map (flatten xs)))

(defn with-mod-chord
  "Joins a chord with a mod chord. If the mod chord is -, and the chord
   contains ^, properly formats the returned chord."
  [mod-chord chord]
  (if (and (= mod-chord "-") (str/starts-with? chord "^"))
    chord
    (str mod-chord chord)))

(defn generate-entries
  "Generates a nested sequence of key value pair entries for each combination
   of prefixes, the starter, the mods, the chords, and the suffixes.
   Calls ->translation with the set of mods, the chord translation, and the
   suffix translation."
  [prefixes starter mods chords suffixes ->translation]
  (for [[prefix-chord prefix-translation] prefixes
        [mod-chord mod-set] mods
        [chord translation] chords
        [suffix-chord suffix-translation] suffixes]
    [(str prefix-chord starter (with-mod-chord mod-chord chord) suffix-chord)
     (str prefix-translation (->translation mod-set translation suffix-translation))]))

(defn repeated [_ translation suffix]
  (apply str (repeat suffix translation)))

(def symbols-dict
  (flatten-map
   (let [{:keys [starter chords shortcuts mod-shortcuts]} symbols
         mapped-symbols (update-vals chords symbol-name)
         symbols-without-mods (update-vals mod-shortcuts :no-mods)
         symbols-with-mods (update-vals mod-shortcuts :with-mods)
         e-repetitions (update-keys repetitions #(str % "e"))
         repeated= #(str (apply repeated %&) "=")]
     [(generate-entries always-attach starter vowel-chords mapped-symbols       no-repetition apply-mods)
      (generate-entries never-attach  starter all-mods     shortcuts            no-repetition apply-mods)
      (generate-entries never-attach  starter no-mods      symbols-without-mods no-repetition repeated)
      (generate-entries never-attach  starter vowel-chords symbols-with-mods    no-repetition apply-mods)
      (generate-entries attach   starter no-mods      chords               repetitions   repeated)
      (generate-entries attach   starter no-mods      chords               e-repetitions repeated=)])))

(def numbers
  {:starter "TPWHR"
   :left {"R" "1"
          "RK" "2"
          "K" "3"
          "LR" "4"
          "LRPK" "5"
          "PK" "6"
          "L" "7"
          "LP" "8"
          "P" "9"
          "LRK" "0"
          "LRP" "0"
          "RPK" "0"
          "LPK" "0"
          "" ""}
   :right {"S" "1"
           "S*" "2"
           "*" "3"
           "FS" "4"
           "FST*" "5"
           "T*" "6"
           "F" "7"
           "FT" "8"
           "T" "9"
           "FST" "0"
           "FS*" "0"
           "ST*" "0"
           "FT*" "0"
           "" ""}
   :F-starter "TPWHR&"
   :F-keys {"R"    "F1"  "S"    "F1"
            "RK"   "F2"  "S*"   "F2"
            "K"    "F3"  "*"    "F3"
            "LR"   "F4"  "FS"   "F4"
            "LRPK" "F5"  "FST*" "F5"
            "PK"   "F6"  "T*"   "F6"
            "L"    "F7"  "F"    "F7"
            "LP"   "F8"  "FT"   "F8"
            "P"    "F9"  "T" "F9"
            "RFST" "F10"
            "RFS*" "F10"
            "RST*" "F10"
            "RFT*" "F10"
            "RS"   "F11"
            "RS*"  "F12"}})

(def numbers-dict
  (flatten-map
   (let [{:keys [starter left right F-starter F-keys]} numbers]
     [(generate-entries always-attach starter vowel-chords (merge left right) no-repetition apply-mods)
      (generate-entries never-attach F-starter all-mods F-keys no-repetition apply-mods)
      (generate-entries attach starter
                        {"" "" "^" "0"}
                        (for [[left-chord left-number] left
                              [right-chord right-number] right]
                          [(str left-chord right-chord) (str left-number right-number)])
                        {"" "" "e" "00"}
                        (fn [zeroes n suffix] (str n zeroes suffix)))])))

(def movement-starter "PWH")
(def movement-chords
  {"R" "left"
   "P" "up"
   "K" "down"
   "S" "right"
   "LPF" "page_up"
   "RKS" "page_down"
   "LR" "home"
   "FS" "end"})

(def movement-dict
  (flatten-map
   (generate-entries never-attach movement-starter all-mods movement-chords no-repetition apply-mods)))

(def fingerspelling-starter "TWR")
(def letters
  {"LRPK" "a"
   "PK" "b"
   "PKS" "c"
   "PKF" "d"
   "LRPKS" "e"
   "F" "f"
   "PKFS" "g"
   "KT" "h"
   "KT*" "h" ; Porque no
   "LR" "i"
   "KST*" "j"
   "KST" "j" ; Here as a misstroke because why not
   "K" "k"
   "L" "l"
   "PS" "m"
   "PF" "n"
   "LRPKFS" "o"
   "P" "p"
   "KF*" "q"
   "KF" "q" ; Again, why not
   "R" "r"
   "S" "s"
   "T" "t"
   "LRKFS" "u"
   "FS" "v"
   "PF*" "w"
   "KS" "x"
   "PFT" "y"
   "PFS" "z"})

(def fingerspelling-dict
  (flatten-map
   [(generate-entries never-attach fingerspelling-starter
                      vowel-chords letters no-repetition apply-mods)
    (generate-entries attach-and-capitalize fingerspelling-starter
                      no-mods letters no-repetition (fn [_ translation _] translation))]))

(spit "pinchord-mods.json" (json/generate-string (merge symbols-dict fingerspelling-dict numbers-dict movement-dict)))