0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 16:00:19 -05:00

📎 Minor improvements to translations scripts.

This commit is contained in:
Andrey Antukh 2021-04-14 15:43:17 +02:00
parent 5a49ce2028
commit bb719d6211
5 changed files with 52 additions and 170 deletions

View file

@ -1,151 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(require '[clojure.pprint :as pp :refer [pprint]])
(require '[clojure.edn :as edn]
'[clojure.set :as set]
'[clojure.java.io :as io])
(require '[datoteka.core :as fs]
'[jsonista.core :as json]
'[parcera.core :as pa])
(import 'java.nio.file.Paths
'java.nio.file.Path
'java.nio.file.Files
'java.nio.file.SimpleFileVisitor
'java.nio.file.FileVisitResult
'com.fasterxml.jackson.databind.ObjectMapper
'com.fasterxml.jackson.databind.SerializationFeature)
(defmulti task first)
(defn- find-translations-in-form
[form]
(reduce (fn [messages node]
(let [found (->> node
(filter #(and (seq? %) (= :string (first %))))
(map (fn [item]
(let [mdata (meta item)]
{:code (edn/read-string (second item))
:line (get-in mdata [::pa/start :row])}))))]
(into messages found)))
[]
(->> (tree-seq seq? seq form)
(filter #(and (seq? %)
(seq? (second %))
(= :list (first %))
(= :symbol (first (second %)))
(or (= "t" (second (second %)))
(= "tr" (second (second %)))))))))
(defn- find-translations
[path]
(let [forms (pa/ast (slurp path))
spath (str path)]
(->> forms
(filter #(and (seq? %) (= :list (first %))))
(reduce (fn [messages form]
(->> (find-translations-in-form form)
(map #(assoc % :file spath))
(into messages))) []))))
(defn- collect-translations
[path]
(let [messages (atom [])]
(->> (proxy [SimpleFileVisitor] []
(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
[path]
(when (fs/regular-file? path)
(let [content (json/read-value (io/as-file path))]
(reduce-kv (fn [res k v]
(let [v (into (sorted-map) v)
v (update v "translations" #(into (sorted-map) %))]
(assoc res k v)))
(sorted-map)
content))))
(defn- add-translation
[data {:keys [code file line] :as translation}]
(let [rpath (str file)]
(if (contains? data code)
(update data code (fn [state]
(if (get state "permanent")
state
(-> state
(dissoc "unused")
(update "used-in" conj rpath)))))
(assoc data code {"translations" (sorted-map "en" nil "es" nil)
"used-in" [rpath]}))))
(defn- clean-removed-translations
[data imported]
(let [existing (into #{} (keys data))
toremove (set/difference existing imported)]
(reduce (fn [data code]
(if (get-in data [code "permanent"])
data
(-> data
(update code dissoc "used-in")
(update code assoc "unused" true))))
data
toremove)))
(defn- initial-cleanup
[data]
(reduce-kv (fn [data k v]
(if (string? v)
(assoc data k {"used-in" []
"translations" {:en v}})
(update data k assoc "used-in" [])))
data
data))
(defn- synchronize-translations
[data translations]
(loop [data (initial-cleanup data)
imported #{}
c (first translations)
r (rest translations)]
(if (nil? c)
(clean-removed-translations data imported)
(recur (add-translation data c)
(conj imported (:code c))
(first r)
(rest r)))))
(defn- write-result!
[data output-path]
(binding [*out* (io/writer (fs/path output-path))]
(let [mapper (doto (ObjectMapper.)
(.enable SerializationFeature/ORDER_MAP_ENTRIES_BY_KEYS))
mapper (json/object-mapper {:pretty true :mapper mapper})]
(println (json/write-value-as-string data mapper))
(flush))))
(defn- update-translations
[{:keys [find-directory output-path] :as props}]
(let [data (read-json-file output-path)
translations (collect-translations find-directory)
data (synchronize-translations data translations)]
(write-result! data output-path)))
(defmethod task "collect"
[[_ in-path out-path]]
(update-translations {:find-directory in-path
:output-path out-path}))
(task *command-line-args*)

View file

@ -12,7 +12,7 @@
"defaults"
],
"scripts": {
"collect-locales": "clojure -M:dev locales.clj collect src/app/main/ resources/locales.json"
"validate-translations": "node ./scripts/validate-translations.js"
},
"devDependencies": {
"autoprefixer": "^10.2.4",

View file

@ -0,0 +1,31 @@
const fs = require('fs').promises;
const gt = require("gettext-parser");
const l = require("lodash");
const path = require('path');
async function* getFiles(dir) {
const dirents = await fs.readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
const res = path.resolve(dir, dirent.name);
if (dirent.isDirectory()) {
yield* getFiles(res);
} else {
yield res;
}
}
}
;(async () => {
const fileRe = /.+\.po$/;
const target = path.normalize("./translations/");
const parent = path.join(target, "..");
for await (const f of getFiles(target)) {
if (!fileRe.test(f)) continue;
const entry = path.relative(parent, f);
console.log(`=> processing: ${entry}`);
const content = await fs.readFile(f);
const data = gt.po.parse(content, "utf-8")
const buff = gt.po.compile(data, {sort: true});
await fs.writeFile(f, buff);
}
})()

View file

@ -1423,6 +1423,14 @@ msgstr "Colors"
msgid "workspace.assets.components"
msgstr "Components"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group"
msgstr "Create a group"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group-hint"
msgstr "Your items are going to be named automatically as \"group name / item name\""
#: src/app/main/ui/workspace/sidebar/sitemap.cljs, src/app/main/ui/workspace/sidebar/assets.cljs, src/app/main/ui/workspace/sidebar/assets.cljs, src/app/main/ui/workspace/sidebar/assets.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.delete"
msgstr "Delete"
@ -1447,18 +1455,10 @@ msgstr "Graphics"
msgid "workspace.assets.group"
msgstr "Group"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group"
msgstr "Create a group"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.group-name"
msgstr "Group name"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group-hint"
msgstr "Your items are going to be named automatically as \"group name / item name\""
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.libraries"
msgstr "Libraries"
@ -2457,4 +2457,4 @@ msgid "workspace.updates.update"
msgstr "Update"
msgid "workspace.viewport.click-to-close-path"
msgstr "Click to close the path"
msgstr "Click to close the path"

View file

@ -1403,6 +1403,16 @@ msgstr "Colores"
msgid "workspace.assets.components"
msgstr "Componentes"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group"
msgstr "Crear un grupo"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group-hint"
msgstr ""
"Tus elementos se renombrarán automáticamente a \"nombre grupo / nombre "
"elemento\""
#: src/app/main/ui/workspace/sidebar/sitemap.cljs, src/app/main/ui/workspace/sidebar/assets.cljs, src/app/main/ui/workspace/sidebar/assets.cljs, src/app/main/ui/workspace/sidebar/assets.cljs, src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.delete"
msgstr "Borrar"
@ -1427,18 +1437,10 @@ msgstr "Gráficos"
msgid "workspace.assets.group"
msgstr "Agrupar"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group"
msgstr "Crear un grupo"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.group-name"
msgstr "Nombre del grupo"
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.create-group-hint"
msgstr "Tus elementos se renombrarán automáticamente a \"nombre grupo / nombre elemento\""
#: src/app/main/ui/workspace/sidebar/assets.cljs
msgid "workspace.assets.libraries"
msgstr "Bibliotecas"
@ -2439,4 +2441,4 @@ msgid "workspace.updates.update"
msgstr "Actualizar"
msgid "workspace.viewport.click-to-close-path"
msgstr "Pulsar para cerrar la ruta"
msgstr "Pulsar para cerrar la ruta"