0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-23 06:58:58 -05:00

♻️ Rewrite translations messages collection using gramar based parser.

This commit is contained in:
Andrey Antukh 2020-01-21 21:28:29 +01:00
parent abb19572b5
commit 24677a3266
4 changed files with 83 additions and 80 deletions

View file

@ -61,7 +61,7 @@ command for reformat the file, and track the usage locations (the
"used-in" list) before commiting the file into the repository: "used-in" list) before commiting the file into the repository:
```bash ```bash
clojure -Adev translations.clj collectmessages src/uxbox/main/ resources/locales.json clojure -Adev locales.clj collect src/uxbox/main/ resources/locales.json
``` ```
NOTE: Later, we will need to think and implement the way to export and NOTE: Later, we will need to think and implement the way to export and

View file

@ -27,7 +27,13 @@
com.bhauman/figwheel-main {:mvn/version "0.2.3"} com.bhauman/figwheel-main {:mvn/version "0.2.3"}
org.clojure/tools.namespace {:mvn/version "0.3.1"} org.clojure/tools.namespace {:mvn/version "0.3.1"}
metosin/jsonista {:mvn/version "0.2.5"} metosin/jsonista {:mvn/version "0.2.5"}
funcool/datoteka {:mvn/version "1.2.0"}} funcool/datoteka {:mvn/version "1.2.0"}
;; i18n parsing
carocad/parcera {:mvn/version "0.11.0"}
org.antlr/antlr4-runtime {:mvn/version "4.7"}}
:extra-paths ["test"]} :extra-paths ["test"]}
:repl :repl

View file

@ -1,16 +1,12 @@
(require '[clojure.pprint :as pp :refer [pprint]]) (require '[clojure.pprint :as pp :refer [pprint]])
(require '[clojure.java.shell :as shell])
(require '[environ.core :refer [env]])
(require '[clojure.walk :as walk] (require '[clojure.edn :as edn]
'[clojure.edn :as edn] '[clojure.set :as set]
'[clojure.set :as set]) '[clojure.java.io :as io])
(require '[datoteka.core :as fs] (require '[datoteka.core :as fs]
'[jsonista.core :as json]) '[jsonista.core :as json]
(require '[clojure.java.io :as io] '[parcera.core :as pa])
'[clojure.tools.reader :as r]
'[clojure.tools.reader.reader-types :as rt])
(import 'java.nio.file.Paths (import 'java.nio.file.Paths
'java.nio.file.Path 'java.nio.file.Path
@ -18,74 +14,51 @@
'java.nio.file.SimpleFileVisitor 'java.nio.file.SimpleFileVisitor
'java.nio.file.FileVisitResult) 'java.nio.file.FileVisitResult)
(extend-protocol io/Coercions
Path
(as-file [it] (.toFile it))
(as-url [it] (io/as-url (.toFile it))))
(defmulti task first) (defmulti task first)
(defn- find-translations-in-form (defn- find-translations-in-form
[env form] [form]
(->> form (let [messages (atom [])]
(walk/postwalk (run! (fn [node]
(fn [fm] (let [found (->> node
(cond (filter #(and (seq? %) (= :string (first %))))
(and (list? fm) (map (fn [item]
(= (first fm) 'tr) (let [mdata (meta item)]
(string? (second fm))) {:code (edn/read-string (second item))
(let [m (meta (first fm))] :line (get-in mdata [::pa/start :row])}))))]
(swap! env conj {:code (second fm) (swap! messages into found)))
:file (:file m) (->> (tree-seq seq? seq form)
:line (:line m)})) (filter #(and (seq? %)
(seq? (second %))
(= :list (first %))
(= :symbol (first (second %)))
(or (= "t" (second (second %)))
(= "tr" (second (second %))))))))
@messages))
(and (list? fm) (defn- find-translations
(= (first fm) 't) [path]
(symbol? (second fm))) (let [forms (pa/ast (slurp path))
(let [m (meta (first fm)) spath (str path)]
code (first (drop 2 fm))] (->> forms
(swap! env conj {:code code (filter #(and (seq? %) (= :list (first %))))
:file (:file m) (reduce (fn [messages form]
:line (:line m)}))) (->> (find-translations-in-form form)
fm)))) (map #(assoc % :file spath))
(into messages))) []))))
(defn- find-translations-in-file
[env file]
(let [rdr (-> (io/as-file file)
(io/reader)
(rt/source-logging-push-back-reader 1 file))]
(try
(binding [r/*default-data-reader-fn* (constantly nil)
r/*alias-map* {'dw (create-ns 'user)
'fm (create-ns 'user)
'us (create-ns 'user)
'dp (create-ns 'user)
'cp (create-ns 'user)}]
(loop []
(let [form (r/read {:eof ::end} rdr)]
(when (not= ::end form)
(find-translations-in-form env form)
(recur)))))
(catch Exception e
;; (.printStackTrace e)
(println (str "ERROR: on procesing " file "; ignoring..."))))))
(defn- find-translations-in-directory
[env file]
(->> (proxy [SimpleFileVisitor] []
(visitFile [path attrs]
(when (= (fs/ext path) "cljs")
(find-translations-in-file env path))
FileVisitResult/CONTINUE)
(postVisitDirectory [dir exc]
FileVisitResult/CONTINUE))
(Files/walkFileTree (fs/path file))))
(defn- collect-translations (defn- collect-translations
[path] [path]
(let [env (atom [])] (let [messages (atom [])]
(find-translations-in-directory env path) (->> (proxy [SimpleFileVisitor] []
@env)) (visitFile [path attrs]
(when (= (fs/ext path) "cljs")
(swap! messages into (find-translations path)))
FileVisitResult/CONTINUE)
(postVisitDirectory [dir exc]
FileVisitResult/CONTINUE))
(Files/walkFileTree (fs/path path)))
@messages))
(defn- read-json-file (defn- read-json-file
[path] [path]
@ -167,16 +140,19 @@
(defn- update-translations (defn- update-translations
[{:keys [find-directory output-path] :as props}] [{:keys [find-directory output-path] :as props}]
(let [data (read-json-file output-path) (let [
data (read-json-file output-path)
translations (collect-translations find-directory) translations (collect-translations find-directory)
data (synchronize-translations data translations)] data (synchronize-translations data translations)
]
(write-result! data output-path))) (write-result! data output-path)))
(defmethod task "collectmessages" (defmethod task "collect"
[[_ in-path out-path]] [[_ in-path out-path]]
(update-translations {:find-directory in-path (update-translations {:find-directory in-path
:output-path out-path})) :output-path out-path}))
(defmethod task "merge-with-legacy" (defmethod task "merge-with-legacy"
[[_ path lang legacy-path]] [[_ path lang legacy-path]]
(let [ldata (read-edn-file legacy-path) (let [ldata (read-edn-file legacy-path)

View file

@ -196,6 +196,13 @@
"fr" : null "fr" : null
} }
}, },
"ds.num-elements" : {
"translations" : {
"en" : null,
"fr" : null
},
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:111" ]
},
"ds.position" : { "ds.position" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/icon_measures.cljs:52" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/icon_measures.cljs:52" ],
"translations" : { "translations" : {
@ -231,6 +238,13 @@
"fr" : null "fr" : null
} }
}, },
"ds.settings.icons" : {
"translations" : {
"en" : null,
"fr" : null
},
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/icons.cljs:72" ]
},
"ds.size" : { "ds.size" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/icon_measures.cljs:33" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/icon_measures.cljs:33" ],
"translations" : { "translations" : {
@ -567,6 +581,13 @@
"fr" : "Votre nom d'utilisateur" "fr" : "Votre nom d'utilisateur"
} }
}, },
"settings.exit" : {
"translations" : {
"en" : null,
"fr" : null
},
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:46" ]
},
"settings.notifications" : { "settings.notifications" : {
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:43" ], "used-in" : [ "src/uxbox/main/ui/settings/header.cljs:43" ],
"translations" : { "translations" : {
@ -862,7 +883,7 @@
} }
}, },
"workspace.options.measures" : { "workspace.options.measures" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:115", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:62", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:65", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:70" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:115", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:62", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:65", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:67", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:70", "src/uxbox/main/ui/workspace/sidebar/options/canvas.cljs:51" ],
"translations" : { "translations" : {
"en" : "Size, position & rotation", "en" : "Size, position & rotation",
"fr" : "Taille, position et rotation" "fr" : "Taille, position et rotation"
@ -876,21 +897,21 @@
} }
}, },
"workspace.options.position" : { "workspace.options.position" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:74", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:91", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:99" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:74", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:91", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:93", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:96", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:99", "src/uxbox/main/ui/workspace/sidebar/options/canvas.cljs:80" ],
"translations" : { "translations" : {
"en" : "Position", "en" : "Position",
"fr" : "Position" "fr" : "Position"
} }
}, },
"workspace.options.rotation-radius" : { "workspace.options.rotation-radius" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:92", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:110", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:116" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:92", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:113", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:116" ],
"translations" : { "translations" : {
"en" : "Rotation & Radius", "en" : "Rotation & Radius",
"fr" : "TODO" "fr" : "TODO"
} }
}, },
"workspace.options.size" : { "workspace.options.size" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:38", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:72" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:38", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:72", "src/uxbox/main/ui/workspace/sidebar/options/canvas.cljs:53" ],
"translations" : { "translations" : {
"en" : "Size", "en" : "Size",
"fr" : "Taille" "fr" : "Taille"
@ -953,7 +974,7 @@
} }
}, },
"workspace.sidebar.layers" : { "workspace.sidebar.layers" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/layers.cljs:261" ], "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/layers.cljs:289" ],
"translations" : { "translations" : {
"en" : "Layers", "en" : "Layers",
"fr" : "Couches" "fr" : "Couches"