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:
parent
abb19572b5
commit
24677a3266
4 changed files with 83 additions and 80 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Reference in a new issue