Skip to content

Commit

Permalink
Refactor and simplify dicts
Browse files Browse the repository at this point in the history
- frontend.dicts encapsulates dicts behavior for all other namespaces
- Each dict ns only has one var which prepares us
- No longer need shortcut.dicts
- Fix remaining lints that were broken
- Also bring back frontend.dicts
- Update guide
- Add a false binding to :editor/toggle-undo-redo-mode which throws a
  needless warning
  • Loading branch information
logseq-cldwalker committed May 18, 2023
1 parent 0434a2b commit 514b5fa
Show file tree
Hide file tree
Showing 28 changed files with 383 additions and 446 deletions.
45 changes: 20 additions & 25 deletions docs/contributing-to-translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ In order to run the commands in this doc, you will need to install

## Where to Contribute

Language translations in this library,
[src/main/frontend/dicts/](https://github.com/logseq/logseq/blob/master/src/main/frontend/dicts/), `<LOCALE>.cljc` file the isolated packages for each language.
Language translations are under,
[src/main/frontend/dicts/](https://github.com/logseq/logseq/blob/master/src/main/frontend/dicts/) with each language having it's own file. For example, the es locale is in `es.cljc `.

## Language Overview

Expand Down Expand Up @@ -52,16 +52,15 @@ Let's try to get your language translated as close to 100% as you can!

## Edit a Language

To see what translations are missing for your language use:
To see what translations are missing for your language, let's run a command using `es` as the example language:

```shell
$ bb lang:missing LOCALE
| :translation-key | :string-to-translate | :file |
|---------------------------------------------+---------------------------------------------+---------------------|
| :content/copy-block-url | Copy block URL | frontend/dicts/core.cljs |
| :content/copy-export-as | Copy / Export as.. | frontend/dicts/core.cljs |
| :content/copy-ref | Copy this reference | frontend/dicts/core.cljs |
| :content/delete-ref | Delete this reference | frontend/dicts/core.cljs |
$ bb lang:missing es
| :translation-key | :string-to-translate | :file |
|---------------------------------------+-------------------------------------------------------+---------------|
| :command.editor/toggle-number-list | Toggle number list | dicts/es.cljc |
| :command.whiteboard/bring-forward | Move forward | dicts/es.cljc |
| :command.whiteboard/bring-to-front | Move to front | dicts/es.cljc |
...
```

Expand All @@ -70,17 +69,16 @@ Over time you're aiming to have this list drop to zero. Since this process can b

```sh
# When pasting this content, be sure to update the indentation to match the file
$ bb lang:missing LOCALE --copy
$ bb lang:missing es --copy

;; For frontend/dicts.cljs
:content/copy-block-url "Copy block URL"
:content/copy-export-as "Copy / Export as.."
:content/copy-ref "Copy this reference"
:content/delete-ref "Delete this reference"
;; For dicts/es.cljc
:command.editor/toggle-number-list "Toggle number list"
:command.whiteboard/bring-forward "Move forward"
:command.whiteboard/bring-to-front "Move to front"
...
```

Almost all translations are pretty quick. The only exceptions to this are the keys `:tutorial/text` and `:tutorial/dummy-notes`. These reference files that are part of the onboarding tutorial. Most languages don't have this translated. If you are willing to do this, we would be happy to have this translated.
Almost all translations are small. The only exceptions to this are the keys `:tutorial/text` and `:tutorial/dummy-notes`. These reference files that are part of the onboarding tutorial. Most languages don't have this translated. If you are willing to do this, we would be happy to have this translated.

## Fix Untranslated

Expand All @@ -106,11 +104,8 @@ and tell you what's wrong.

## Add a Language

To add a new language you must create a new file in the `frontend.dicts` namespace containing two variables:

- **application `(def application ...)`:** translation of the application into the idiom
- **shortcuts `(def shortcuts ...)`:** shortcut translation

Use as base the main language file `frontend/dicts/en.cljs`.

After creating the language pack you should add the `application` variable to `frontend.dicts.core` and the `shortcuts` variable to `frontend.modules.shortcut.dicts`.
To add a new language:
* Add an entry to `frontend.dicts/languages`
* Create a new file under `src/main/frontend/dicts/` and name the file the same as the locale e.g. zz.cljc for a hypothetical zz locale.
* Add a `(def dicts {})` in that file and then add a entry in the `dicts` map in `src/main/frontend/dicts.cljc`.
* Then start translating for your language and adding entries in your language's `dicts` using the `bb lang:missing` workflow.
44 changes: 18 additions & 26 deletions scripts/src/logseq/tasks/lang.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
"Tasks related to language translations"
(:require [clojure.set :as set]
[clojure.string :as string]
[frontend.dicts.core :as dicts]
[frontend.modules.shortcut.dicts :as shortcut-dicts]
[frontend.dicts :as dicts]
[logseq.tasks.util :as task-util]
[babashka.cli :as cli]
[babashka.process :refer [shell]]))

(defn- get-dicts
[]
(dissoc dicts/dicts :tongue/fallback))

(defn- get-all-dicts
[]
(merge-with merge (get-dicts) shortcut-dicts/dicts))
dicts/dicts)

(defn- get-languages
[]
Expand All @@ -25,7 +20,7 @@
(defn list-langs
"List translated langagues with their number of translations"
[]
(let [dicts (get-all-dicts)
(let [dicts (get-dicts)
en-count (count (dicts :en))
langs (get-languages)]
(->> dicts
Expand All @@ -52,24 +47,20 @@
_ (when-not (contains? (get-languages) lang)
(println "Language" lang "does not have an entry in dicts/core.cljs")
(System/exit 1))
all-dicts [[(get-dicts) "frontend/dicts/core.cljs"]
[shortcut-dicts/dicts "shortcut/dicts.cljs"]]
all-missing (map (fn [[dicts file]]
[(select-keys (dicts :en)
(set/difference (set (keys (dicts :en)))
(set (keys (dicts lang)))))
file])
all-dicts)]
(if (every? (comp zero? count first) all-missing)
dicts (get-dicts)
all-missing (select-keys (dicts :en)
(set/difference (set (keys (dicts :en)))
(set (keys (dicts lang)))))]
(if (-> all-missing count zero?)
(println "Language" lang "is fully translated!")
(let [sorted-missing (->> all-missing
(mapcat (fn [[m file]]
(map (fn [[k v]]
{:translation-key k
(map (fn [[k v]]
{:translation-key k
;; Shorten values
:string-to-translate (shorten v 50)
:file file})
m)))
:string-to-translate (shorten v 50)
:file (str "dicts/"
(-> lang name (string/replace "-" "_") string/lower-case)
".cljc")}))
(sort-by (juxt :file :translation-key)))]
(if (:copy options)
(doseq [[file missing-for-file] (group-by :file sorted-missing)]
Expand All @@ -84,7 +75,7 @@
language. This catches mistakes where another language has accidentally typoed
keys or added ones without updating :en"
[]
(let [dicts (get-all-dicts)
(let [dicts (get-dicts)
;; For now defined as :en but clj-kondo analysis could be more thorough
valid-keys (set (keys (dicts :en)))
invalid-dicts
Expand Down Expand Up @@ -137,7 +128,8 @@
(map #(keyword (subs % 4)))
(concat (mapcat val manual-ui-dicts))
set)
expected-dicts (set (keys (:en (get-dicts))))
expected-dicts (set (remove #(re-find #"^(command|shortcut)\." (str (namespace %)))
(keys (:en (get-dicts)))))
actual-only (set/difference actual-dicts expected-dicts)
expected-only (set/difference expected-dicts actual-dicts)]
(if (and (empty? actual-only) (empty? expected-only))
Expand All @@ -160,7 +152,7 @@
(defn list-duplicates
"Lists translations that are the same as the one in English"
[& args]
(let [dicts (get-all-dicts)
(let [dicts (get-dicts)
en-dicts (dicts :en)
lang (or (keyword (first args))
(task-util/print-usage "LOCALE"))
Expand Down
2 changes: 1 addition & 1 deletion src/main/frontend/components/settings.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[frontend.storage :as storage]
[frontend.spec.storage :as storage-spec]
[frontend.date :as date]
[frontend.dicts.core :as dicts]
[frontend.dicts :as dicts]
[frontend.handler :as handler]
[frontend.handler.config :as config-handler]
[frontend.handler.notification :as notification]
Expand Down
6 changes: 2 additions & 4 deletions src/main/frontend/context/i18n.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
"This ns is a system component that handles translation for the entire
application. The ns dependencies for this ns must be small since it is used
throughout the application."
(:require [frontend.dicts.core :as dicts]
[frontend.modules.shortcut.dicts :as shortcut-dicts]
(:require [frontend.dicts :as dicts]
[tongue.core :as tongue]
[frontend.state :as state]))

(def dicts
(merge-with merge dicts/dicts shortcut-dicts/dicts))
(def dicts (merge dicts/dicts {:tongue/fallback :en}))

(def translate
(tongue/build-translate dicts))
Expand Down
84 changes: 84 additions & 0 deletions src/main/frontend/dicts.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
(ns ^:bb-compatible frontend.dicts
"Provides dictionary entries for most of the application"
(:require [frontend.dicts.en :as en]
[frontend.dicts.de :as de]
[frontend.dicts.nl :as nl]
[frontend.dicts.fr :as fr]
[frontend.dicts.zh-cn :as zh-CN]
[frontend.dicts.zh-hant :as zh-Hant]
[frontend.dicts.af :as af]
[frontend.dicts.es :as es]
[frontend.dicts.nb-no :as nb-NO]
[frontend.dicts.pt-br :as pt-BR]
[frontend.dicts.pt-pt :as pt-PT]
[frontend.dicts.ru :as ru]
[frontend.dicts.ja :as ja]
[frontend.dicts.it :as it]
[frontend.dicts.tr :as tr]
[frontend.dicts.ko :as ko]
[frontend.dicts.pl :as pl]
[frontend.dicts.sk :as sk]
[frontend.dicts.uk :as uk]))

(def categories
"Shortcut categories described in default language"
(set (filter #(= "shortcut.category" (namespace %)) (keys en/dicts))))

(def abbreviated-commands
"Commands defined in default language and in a format that
frontend.modules.shortcut.* namespaces understand e.g. :date-picker/complete
instead of :command.date-picker/complete"
(set (keys (:commands en/dicts))))

(defn- decorate-namespace [k]
(let [n (name k)
ns (namespace k)]
(keyword (str "command." ns) n)))

(def ^:private en-dicts
(merge (dissoc en/dicts :commands)
;; Dynamically add :command ns prefix since command descriptions have to
;; stay in sync with frontend.modules.shortcut.config keywords which do not
;; have the prefix
(update-keys (:commands en/dicts) decorate-namespace)))

(def dicts
{:en en-dicts
:de de/dicts
:nl nl/dicts
:fr fr/dicts
:zh-CN zh-CN/dicts
:zh-Hant zh-Hant/dicts
:af af/dicts
:es es/dicts
:nb-NO nb-NO/dicts
:pt-BR pt-BR/dicts
:pt-PT pt-PT/dicts
:ru ru/dicts
:ja ja/dicts
:it it/dicts
:tr tr/dicts
:ko ko/dicts
:pl pl/dicts
:sk sk/dicts
:uk uk/dicts})

(def languages [{:label "English" :value :en}
{:label "Français" :value :fr}
{:label "Deutsch" :value :de}
{:label "Dutch (Nederlands)" :value :nl}
{:label "简体中文" :value :zh-CN}
{:label "繁體中文" :value :zh-Hant}
{:label "Afrikaans" :value :af}
{:label "Español" :value :es}
{:label "Norsk (bokmål)" :value :nb-NO}
{:label "Polski" :value :pl}
{:label "Português (Brasileiro)" :value :pt-BR}
{:label "Português (Europeu)" :value :pt-PT}
{:label "Русский" :value :ru}
{:label "日本語" :value :ja}
{:label "Italiano" :value :it}
{:label "Türkçe" :value :tr}
{:label "Українська" :value :uk}
{:label "한국어" :value :ko}
{:label "Slovenčina" :value :sk}])
9 changes: 4 additions & 5 deletions src/main/frontend/dicts/af.cljc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns frontend.dicts.af
"Provides translation to AF")

(def application
(def ^:large-vars/data-var dicts
{:on-boarding/demo-graph "This is a demo graph, changes will not be saved until you open a local folder."
:on-boarding/add-graph "Add a graph"
:on-boarding/open-local-dir "Open a local directory"
Expand Down Expand Up @@ -85,10 +85,9 @@
:language "Taal"

:file-sync/other-user-graph "Huidige plaaslike grafiek is gebonde aan ander gebruiker se afgeleë grafiek. So kan nie begin om te sinkroniseer nie."
:file-sync/graph-deleted "Huidige afstandgrafiek is geskrap"})
:file-sync/graph-deleted "Huidige afstandgrafiek is geskrap"

(def shortcuts
{:shortcut.category/formatting "Formatering"
:shortcut.category/formatting "Formatering"
:command.editor/indent "Ingekeepte blok oortjie"
:command.editor/outdent "Oningekeepte blok"
:command.editor/move-block-up "Skuif Blok Boontoe"
Expand All @@ -110,4 +109,4 @@
:command.ui/toggle-document-mode "Wissel dokument modus"
:command.go/journals "Spring na joernale"
:command.ui/toggle-theme "Wissel tussen donker/lig temas"
:command.ui/toggle-right-sidebar "Wissel regter sybalk"})
:command.ui/toggle-right-sidebar "Wissel regter sybalk"})
62 changes: 0 additions & 62 deletions src/main/frontend/dicts/core.cljc

This file was deleted.

Loading

0 comments on commit 514b5fa

Please sign in to comment.