Skip to content

Commit 67d24c8

Browse files
authored
Merge pull request #332 from KanoComputing/i18n-ja-translations
I18n support and Japanese translations
2 parents 3e54c89 + ea0e226 commit 67d24c8

File tree

109 files changed

+5577
-287
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+5577
-287
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
www/*.html
2-
www/*/*.html
2+
www/**/*.html
33
www/css/*.css
44
www/js/index.js
55
www/assets/challenges/descriptors

TRANSLATION.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Translation
2+
3+
Translation files are found in the following directories:
4+
- `lib/challenges/locales`: translation of the challenges
5+
- `locales`: translation of the views
6+
- `content/docs.json`: translation of the documentation
7+
8+
## i18n not released yet
9+
10+
Kano OS is not fully i18n-aware and locales are not installed for end users, yet. You can translate this application, but as of now, users will still see the default English message strings.
11+
12+
## Build
13+
14+
Translations are part of the normal build process: when you type `npm run build`, the translated challenges and docs will be copied in the `www` directory; and the view templates will be localized by mapping the resources _for each language_. So it means that all resources (views, challenges and docs translations) are prepared in advance.
15+
16+
## Runtime
17+
18+
At runtime, the proper translation will be picked based on the browser language.
19+
20+
## How to add a new translation
21+
22+
You need to add the new language in 4 places:
23+
24+
1. Create `lib/challenges/locales/<locale>` and copy the whole `worlds` directory and `index.json`
25+
These are the translations of the challenges, the main content of Make-Art.
26+
27+
2. Create `locales/<locale>` and copy the content of `locales/en`
28+
These are the translations of the views
29+
30+
3. Directly edit `content/docs.json` and add your language to the map (at the top level)
31+
32+
4. Add your language to `SUPPORTED_LOCALES` array in `lib/i18n.js`
33+
34+
## How to make sure your code is i18n-aware
35+
36+
For the challenges, if you create a new challenge in English, there is nothing special to do, it can be translated to other languages by copying the .json file to the other locales directories.
37+
38+
For the views (jade templates), you need to enclose all your strings in `${{` and `}}$` as this is the convention used by gulp-html-i18n plugin to find and replace the messages in the view templates. Then, you need to add the new string to the corresponding .json file in the (top-level) `locales` directory. Let's say you want to add a string "Happy Birthday" to the challenge.jade template; you would write it as follows in the challenge.jade: `${{ challenge.hapy_birthday }}$`. Then, you would add an entry to the challenge.json map, like:
39+
```
40+
{
41+
...
42+
"happy_birthday": "Happy Birthday"
43+
}
44+
```
45+
46+
Finally, for the documentation, if you add / modify text in `content/docs.json` the translations will need to be added for other languages, in the same file.
47+
48+
## To-Do
49+
50+
Tool to make it easier to add new languages.

content/docs.json

Lines changed: 269 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[
1+
{ "en": [
22
{
33
"label" : "Shapes",
44
"icon" : "shapes",
@@ -263,6 +263,274 @@
263263
"defaults": [ "black", 50 ]
264264
}
265265

266+
]
267+
}
268+
], "ja" : [
269+
{
270+
"label" : "",
271+
"icon" : "shapes",
272+
"commands" : [
273+
{
274+
"call" : "circle",
275+
"unlockedAt" : 1,
276+
"description" : "円形を描く",
277+
"args" : [
278+
[ "radius", "number", "円形の大きさ(半径)", true ]
279+
],
280+
"defaults": [ 100 ]
281+
},
282+
{
283+
"call" : "ellipse",
284+
"unlockedAt" : 999,
285+
"description" : "楕円を描く",
286+
"args" : [
287+
[ "radius-x", "number", "楕円の横幅", true ],
288+
[ "radius-y", "number", "楕円の高さ", true ]
289+
],
290+
"defaults": [ 50, 100 ]
291+
},
292+
{
293+
"call" : "square",
294+
"unlockedAt" : 2,
295+
"description" : "四角を描く",
296+
"args" : [
297+
[ "size", "number", "四角の大きさ", true ]
298+
],
299+
"defaults": [ 200 ]
300+
},
301+
{
302+
"call" : "rectangle",
303+
"unlockedAt" : 999,
304+
"description" : "長方形を描く",
305+
"args" : [
306+
[ "width", "number", "長方形の幅", true ],
307+
[ "height", "number", "長方形の高さ", true ]
308+
],
309+
"defaults": [ 100, 200 ]
310+
},
311+
{
312+
"call" : "arc",
313+
"unlockedAt" : 999,
314+
"description" : "円形の一部を描く",
315+
"args" : [
316+
[ "radius", "number", "大きさ(半径)", true ],
317+
[ "start", "number", "開始点(0〜2)", true ],
318+
[ "end", "number", "最後の点(0〜2)", true ],
319+
[ "close", "bool", "形を閉じるかどうか", false ]
320+
],
321+
"defaults": [ 100, 1, 2, true ]
322+
},
323+
{
324+
"call" : "polygon",
325+
"unlockedAt" : 999,
326+
"description" : "多辺形を描く",
327+
"args" : [
328+
[ "x1", "number", "ー点目のX値", true ],
329+
[ "y1", "number", "ー点目のY値", true ],
330+
[ "...", "", "他の点の位置", true ],
331+
[ "close", "bool", "パスを真ん中に閉じるかどうか", false ]
332+
],
333+
"defaults": [ 0, 0, 100, 0, 100, 100 ]
334+
}
335+
]
336+
},
337+
{
338+
"label" : "",
339+
"icon" : "lines",
340+
"commands" : [
341+
{
342+
"call" : "line",
343+
"unlockedAt" : 3,
344+
"description" : "ある大きさの線を描く",
345+
"args" : [
346+
[ "x", "number", "水平距離", true ],
347+
[ "y", "number", "垂直距離", false ]
348+
],
349+
"defaults": [ 100, 50 ]
350+
},
351+
{
352+
"call" : "lineTo",
353+
"unlockedAt" : 999,
354+
"description" : "ある点までに線を描く",
355+
"args" : [
356+
[ "x", "number", "水平の目的点", true ],
357+
[ "y", "number", "垂直の目的点", true ]
358+
],
359+
"defaults": [ 0, 0 ]
360+
}
361+
]
362+
},
363+
{
364+
"label" : "位置",
365+
"icon" : "position",
366+
"commands" : [
367+
{
368+
"call" : "move",
369+
"unlockedAt" : 6,
370+
"description" : "カーソルをある距離に動かす",
371+
"args" : [
372+
[ "x", "number", "水平距離", true ],
373+
[ "y", "number", "垂直距離", false ]
374+
],
375+
"defaults": [ 100, 50 ]
376+
},
377+
{
378+
"call" : "moveTo",
379+
"unlockedAt" : 999,
380+
"description" : "カーソルをある位置までに動かす",
381+
"args" : [
382+
[ "x", "number", "水平目的点", true ],
383+
[ "y", "number", "垂直目的点", true ]
384+
],
385+
"defaults": [ "center", "center" ]
386+
}
387+
]
388+
},
389+
{
390+
"label" : "テキスト",
391+
"icon" : "text",
392+
"commands" : [
393+
{
394+
"call" : "text",
395+
"unlockedAt" : 999,
396+
"description" : "文字を書く",
397+
"args" : [
398+
[ "message", "string", "メッセージ", true ]
399+
],
400+
"defaults": [ "何か言って!" ]
401+
},
402+
{
403+
"call" : "font",
404+
"unlockedAt" : 999,
405+
"description" : "フォントや大きさを設定",
406+
"args" : [
407+
[ "font", "string", "フォントファミリー名", false ],
408+
[ "size", "number", "ピクセルでのフォントの大きさ", false ]
409+
],
410+
"defaults": [ "Bariol", 30 ]
411+
},
412+
{
413+
"call" : "bold",
414+
"unlockedAt" : 999,
415+
"description" : "太字を有効(true)または無効(false)",
416+
"args" : [
417+
[ "state", "bool", "太字の状態(デフォルトはtrue)", false ]
418+
],
419+
"defaults": [ true ]
420+
},
421+
{
422+
"call" : "italic",
423+
"unlockedAt" : 999,
424+
"description" : "車体を有効(true)または無効(false)",
425+
"args" : [
426+
[ "state", "bool", "車体の状態(デフォルトはtrue)", false ]
427+
],
428+
"defaults": [ true ]
429+
}
430+
]
431+
},
432+
{
433+
"label" : "一般",
434+
"icon" : "general",
435+
"commands" : [
436+
{
437+
"call" : "for",
438+
"unlockedAt" : 9,
439+
"description" : "コードを繰り返す",
440+
"args" : [
441+
[ "i in [x..y]", "number", "i変数の最初と最後の値", true ]
442+
],
443+
"example" : "for i in [1..5]\n circle i",
444+
"defaults": null
445+
},
446+
{
447+
"call" : "random",
448+
"unlockedAt" : 9,
449+
"description" : "ある範囲内でランダムな数字を生成する",
450+
"args" : [
451+
[ "min", "number", "最低値", true ],
452+
[ "max", "number", "最高地", true ],
453+
[ "float", "bool", "trueにすると少数が得られる", false ]
454+
],
455+
"example" : "random 5, 10",
456+
"defaults": [ 5, 10 ]
457+
}
458+
]
459+
},
460+
{
461+
"label" : "",
462+
"icon" : "colors",
463+
"commands" : [
464+
{
465+
"call" : "background",
466+
"unlockedAt" : 999,
467+
"description" : "背景の色を設定する",
468+
"args" : [
469+
[ "color", "string", "設定したい背景の色", true ]
470+
],
471+
"defaults": [ "blue" ]
472+
},
473+
{
474+
"call" : "color",
475+
"unlockedAt" : 4,
476+
"description" : "鉛筆の色を変える",
477+
"args" : [
478+
[ "color", "string", "設定したい鉛筆の色", true ]
479+
],
480+
"defaults": [ "red" ]
481+
},
482+
{
483+
"call" : "stroke",
484+
"unlockedAt" : 5,
485+
"description" : "筆の太さと色を変える",
486+
"args" : [
487+
[ "color", "string", "設定したい色。例えば'red', 'blue'..", false ],
488+
[ "size", "number", "鉛筆の太さ", false ]
489+
],
490+
"defaults": [ 10, "purple" ]
491+
},
492+
{
493+
"call" : "setBrightness",
494+
"unlockedAt" : 999,
495+
"description" : "色の明るさを設定する",
496+
"args" : [
497+
[ "color", "string", "", true ],
498+
[ "amount", "number", "設定したい明るさ(-100〜100)", false ]
499+
],
500+
"defaults": [ "yellow", 30 ]
501+
},
502+
{
503+
"call" : "setSaturation",
504+
"unlockedAt" : 999,
505+
"description" : "色の飽和を設定する",
506+
"args" : [
507+
[ "color", "string", "", true ],
508+
[ "amount", "number", "設定したい飽和(-100〜100)", false ]
509+
],
510+
"defaults": [ "grey", 30 ]
511+
},
512+
{
513+
"call" : "rotate",
514+
"unlockedAt" : 999,
515+
"description" : "色相を回転させる(変更する)",
516+
"args" : [
517+
[ "color", "string", "変えたい色", true ],
518+
[ "amount", "number", "回転の角度(-360〜360)", true ]
519+
],
520+
"defaults": [ "red", 100 ]
521+
},
522+
{
523+
"call" : "setTransparency",
524+
"unlockedAt" : 999,
525+
"description" : "色の透明度を設定する",
526+
"args" : [
527+
[ "color", "string", "", true ],
528+
[ "amount", "number", "引き算する不透明度(-100〜100)", true ]
529+
],
530+
"defaults": [ "black", 50 ]
531+
}
532+
266533
]
267534
}
268535
]
536+
}

0 commit comments

Comments
 (0)