Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/examples/6_Maths_matchingAnglesAndShapes
diff options
context:
space:
mode:
authorPeter <Peter.Gijsels@gmail.com>2010-03-02 22:46:50 (GMT)
committer Peter <Peter.Gijsels@gmail.com>2010-03-02 22:46:50 (GMT)
commitea211eca1f3aebf2381577f0092f494248c617d4 (patch)
treefafaa5f74f9356ee65db5729d9b234fdc9cda014 /examples/6_Maths_matchingAnglesAndShapes
parent15721c5a271c26ac755819dee67f6ae947ff8f89 (diff)
Reworked i18n.
Changes: - using pgettext i.s.o. _c to be consistent with gnu gettext - no longer using 'default' context when there is no context - mo2js.py now deals with contexts - changed the extension for messages file from .json to .js
Diffstat (limited to 'examples/6_Maths_matchingAnglesAndShapes')
-rwxr-xr-xexamples/6_Maths_matchingAnglesAndShapes/index.html2
-rw-r--r--examples/6_Maths_matchingAnglesAndShapes/js/es.po58
-rw-r--r--examples/6_Maths_matchingAnglesAndShapes/js/i18n-notes.txt27
-rwxr-xr-xexamples/6_Maths_matchingAnglesAndShapes/js/lesson.js18
-rw-r--r--examples/6_Maths_matchingAnglesAndShapes/js/messages.es.js46
-rw-r--r--examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json50
-rw-r--r--examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json~13
l---------examples/6_Maths_matchingAnglesAndShapes/js/messages.js1
l---------examples/6_Maths_matchingAnglesAndShapes/js/messages.json1
-rw-r--r--examples/6_Maths_matchingAnglesAndShapes/js/messages.pot48
-rwxr-xr-xexamples/6_Maths_matchingAnglesAndShapes/js/mo2js.py109
11 files changed, 231 insertions, 142 deletions
diff --git a/examples/6_Maths_matchingAnglesAndShapes/index.html b/examples/6_Maths_matchingAnglesAndShapes/index.html
index 5239fc0..22632f4 100755
--- a/examples/6_Maths_matchingAnglesAndShapes/index.html
+++ b/examples/6_Maths_matchingAnglesAndShapes/index.html
@@ -11,7 +11,7 @@
<script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="../../js/jquery.i18n.js"></script>
- <script type="text/javascript" src="./js/messages.es.json"></script>
+ <script type="text/javascript" src="./js/messages.js"></script>
<script type="text/javascript"
src="../../js/ui.core-draggable-resizable-dialog.js"></script>
<script type="text/javascript" src="../../js/ui.kHeader.js"></script>
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/es.po b/examples/6_Maths_matchingAnglesAndShapes/js/es.po
index 095f897..eca4efd 100644
--- a/examples/6_Maths_matchingAnglesAndShapes/js/es.po
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/es.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-28 14:43+0100\n"
+"POT-Creation-Date: 2010-03-02 23:40+0100\n"
"PO-Revision-Date: 2010-02-28 14:58+0100\n"
"Last-Translator: Peter Gijsels <peter.gijsels@gmail.com>\n"
"Language-Team: Spanish\n"
@@ -18,6 +18,46 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+#: ../../../js/ui.kHeader.js:69
+msgctxt "$.ui.kHeader"
+msgid "Lesson Plan"
+msgstr "Plan de Lección"
+
+#: ../../../js/ui.kHeader.js:77
+msgctxt "$.ui.kHeader"
+msgid "Teacher's Note"
+msgstr "Nota de Profesora"
+
+#: ../../../js/ui.kFooter.js:199
+msgctxt "$.ui.kFooter"
+msgid "Score"
+msgstr "Puntos"
+
+#: ../../../js/ui.kFooter.js:204
+msgctxt "$.ui.kFooter"
+msgid "Total"
+msgstr "Total"
+
+#: ../../../js/ui.kFooter.js:217
+msgctxt "$.ui.kFooter"
+msgid "Timer"
+msgstr "Reloj"
+
+#: ../../../js/ui.kFooter.js:241
+msgctxt "$.ui.kFooter"
+msgid "Play Again"
+msgstr "Repite"
+
+#: ../../../js/ui.kFooter.js:256
+msgctxt "$.ui.kFooter"
+msgid "Pause"
+msgstr "Pausa"
+
+#: ../../../js/ui.kFooter.js:271
+msgctxt "$.ui.kFooter"
+msgid "Start"
+msgstr "Comienza"
+
#: lesson.js:61
msgid "Acute-Angle"
msgstr "Ángulo-agudo"
@@ -70,7 +110,7 @@ msgstr "Octágono"
msgid "Maths: Matching Angles with Shapes"
msgstr "Matemáticas: reunir angulos y formas"
-#: lesson.js:100 lesson.js:122
+#: lesson.js:107
#, python-format
msgid ""
"You have completed the game in <span class=\"specialText\">%d</span> clicks "
@@ -78,17 +118,21 @@ msgid ""
msgid_plural ""
"You have completed the game in <span class=\"specialText\">%d</span> clicks "
"within <span class=\"specialText\">%d</span> hours,"
-msgstr[0] "Has acabado el juego en <span class=\"specialText\">%d</span> clics en <span class=\"specialText\">%d</span> hora,"
-msgstr[1] "Has acabado el juego en <span class=\"specialText\">%d</span> clics en <span class=\"specialText\">%d</span> horas,"
-
-#: lesson.js:104 lesson.js:126
+msgstr[0] ""
+"Has acabado el juego en <span class=\"specialText\">%d</span> clics en <span "
+"class=\"specialText\">%d</span> hora,"
+msgstr[1] ""
+"Has acabado el juego en <span class=\"specialText\">%d</span> clics en <span "
+"class=\"specialText\">%d</span> horas,"
+
+#: lesson.js:111
#, python-format
msgid "<span class=\"specialText\">%d</span> minute and "
msgid_plural "<span class=\"specialText\">%d</span> minutes and "
msgstr[0] "<span class=\"specialText\">%d</span> minuto y "
msgstr[1] "<span class=\"specialText\">%d</span> minutos y "
-#: lesson.js:108 lesson.js:130
+#: lesson.js:115
#, python-format
msgid "<span class=\"specialText\">%d</span> second."
msgid_plural "<span class=\"specialText\">%d</span> seconds."
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/i18n-notes.txt b/examples/6_Maths_matchingAnglesAndShapes/js/i18n-notes.txt
new file mode 100644
index 0000000..a620beb
--- /dev/null
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/i18n-notes.txt
@@ -0,0 +1,27 @@
+http://www.gnu.org/software/gettext/manual/gettext.html#Creating
+
+Initially:
+
+1) xgettext --from-code=utf-8 --language=Python -kpgettext:1c,2 ../../../js/ui.kHeader.js ../../../js/ui.kFooter.js lesson.js
+-> creates messages.po
+
+2) mv messages.po messages.pot
+
+3) (locale -a gives a list of possible locales)
+msginit --locale=es_ES
+-> es.po
+
+4) edit es.po
+first line: # add -*- code: UTF-8 -*-
+email address
+charset
+
+5) msgfmt es.po
+-> messages.mo
+
+6) mo2js.py es messages.mo messages.es.js
+-> messages.es.js
+
+When later some messages have changed because the js code changed, replace
+step 3 with msgmerge, e.g.:
+3) msgmerge -o es.new.po ./es.po messages.pot
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/lesson.js b/examples/6_Maths_matchingAnglesAndShapes/js/lesson.js
index 8aef7d8..ce105ba 100755
--- a/examples/6_Maths_matchingAnglesAndShapes/js/lesson.js
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/lesson.js
@@ -6,7 +6,7 @@ Bugs (firefox 3.5.7):
recto iso angulo-recto)
* the text for angulo-obtuso is not displaying properly
* title in english: 'matching angles with shapes' should maybe be
-'matching angles and shapes'
+'matching angles and shapes'
Questions:
* how do we set locale? cfr beginning of $(document).ready()
@@ -96,22 +96,6 @@ $(document).ready(function() {
};
- // example of ngettext usage
- alert(function(clickCounter, h, m, s) {
- return format($.i18n.ngettext('You have completed the game in <span class="specialText">%d</span> clicks within <span class="specialText">%d</span> hour,',
- 'You have completed the game in <span class="specialText">%d</span> clicks within <span class="specialText">%d</span> hours,',
- h),
- clickCounter, h)
- + format($.i18n.ngettext('<span class="specialText">%d</span> minute and ',
- '<span class="specialText">%d</span> minutes and ',
- m),
- m)
- + format ($.i18n.ngettext('<span class="specialText">%d</span> second.',
- '<span class="specialText">%d</span> seconds.',
- s),
- s);
- }(10, 2, 3, 1));
-
var check_game_over = function(){
if(numMatched === NUM_OBJECTS){ //show all
play = 0;
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.js b/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.js
new file mode 100644
index 0000000..6d35e6a
--- /dev/null
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.js
@@ -0,0 +1,46 @@
+$.i18n.es =
+{
+ "strings": {
+ "": "Project-Id-Version: PACKAGE VERSION\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: 2010-03-02 23:40+0100\nPO-Revision-Date: 2010-02-28 14:58+0100\nLast-Translator: Peter Gijsels <peter.gijsels@gmail.com>\nLanguage-Team: Spanish\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=(n != 1);\n",
+ "<span class=\"specialText\">%d</span> minute and ": [
+ "<span class=\"specialText\">%d</span> minuto y ",
+ "<span class=\"specialText\">%d</span> minutos y "
+ ],
+ "Maths: Matching Angles with Shapes": "Matemáticas: reunir angulos y formas",
+ "Square": "Cuadrado",
+ "Triangle": "Triángulo",
+ "Right-Angle": "Ángulo-recto",
+ "Parallelogram": "Paralelogramo",
+ "Octagon": "Octágono",
+ "Rhombus": "Rombo",
+ "You have completed the game in <span class=\"specialText\">%d</span> clicks within <span class=\"specialText\">%d</span> hour,": [
+ "Has acabado el juego en <span class=\"specialText\">%d</span> clics en <span class=\"specialText\">%d</span> hora,",
+ "Has acabado el juego en <span class=\"specialText\">%d</span> clics en <span class=\"specialText\">%d</span> horas,"
+ ],
+ "<span class=\"specialText\">%d</span> second.": [
+ "<span class=\"specialText\">%d</span> segundo.",
+ "<span class=\"specialText\">%d</span> segundos."
+ ],
+ "Septagon": "Heptágono",
+ "Obtuse-Angle": "Ángulo-obtuso",
+ "Hexagon": "Hexágono",
+ "Pentagon": "Pentágono",
+ "Acute-Angle": "Ángulo-agudo",
+ "Rectangle": "Rectángulo"
+ },
+ "contextualized_strings": {
+ "$.ui.kHeader": {
+ "Teacher's Note": "Nota de Profesora",
+ "Lesson Plan": "Plan de Lección"
+ },
+ "$.ui.kFooter": {
+ "Pause": "Pausa",
+ "Timer": "Reloj",
+ "Play Again": "Repite",
+ "Start": "Comienza",
+ "Score": "Puntos",
+ "Total": "Total"
+ }
+ }
+};
+$.i18n.setLocale('es');
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json b/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json
deleted file mode 100644
index f889468..0000000
--- a/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- coding: utf-8 -*- */
-$.i18n.es = {};
-$.i18n.es.strings = {
- "default":{
- 'Acute-Angle' : 'Ángulo-agudo',
- 'Right-Angle' : 'Ángulo-recto',
- 'Obtuse-Angle' : 'Ángulo-obtuso',
- 'Triangle' : 'Triángulo',
- 'Square' : 'Cuadrado',
- 'Rhombus' : 'Rombo',
- 'Rectangle' : 'Rectángulo',
- 'Parallelogram' : 'Paralelogramo',
- 'Pentagon' : 'Pentágono',
- 'Hexagon' : 'Hexágono',
- 'Septagon' : 'Heptágono',
- 'Octagon' : 'Octágono',
- 'Maths: Matching Angles with Shapes' : 'Matemáticas: reunir angulos y formas'
-
- },
- "$.ui.kFooter":{
- "Play Again": "Repite",
- "Pause" : "Pausa",
- "Start" : "Comienza",
- "Timer" : "Reloj",
- "Total" : "Total",
- "Score" : "Puntos"
- },
- "$.ui.kHeader":{
- "Lesson Plan": "Plan de Lección",
- "Teacher's Note": "Nota de Profesora"
- }
-};
-
-(function() { $.i18n.setLocale('es'); })();
-
- $.i18n.setLocale('es');
-
-// You can put these inside the dict above, but for now this will be easier to merge.
-
-
-$.i18n.es.strings['default']['You have completed the game in <span class="specialText">%d</span> clicks within <span class="specialText">%d</span> hour,'] =
- ['Has acabado el juego en <span class="specialText">%d</span> clics en <span class="specialText">%d</span> hora,',
- 'Has acabado el juego en <span class="specialText">%d</span> clics en <span class="specialText">%d</span> horas,'];
-$.i18n.es.strings['default']['<span class="specialText">%d</span> minute and '] =
- ['<span class="specialText">%d</span> minuto y ',
- '<span class="specialText">%d</span> minutos y '];
-$.i18n.es.strings['default']['<span class="specialText">%d</span> second.'] =
- ['<span class="specialText">%d</span> segundo.',
- '<span class="specialText">%d</span> segundos.'];
-
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json~ b/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json~
deleted file mode 100644
index 3b1f550..0000000
--- a/examples/6_Maths_matchingAnglesAndShapes/js/messages.es.json~
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- coding: utf-8 -*- */
-$.i18n.es = {};
-$.i18n.es.strings = {
- "default":{
-
- },
- "$.ui.kHeader":{
-
-
- }
-};
-
-$(function() { $.i18n.setLocale('es'); }); \ No newline at end of file
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/messages.js b/examples/6_Maths_matchingAnglesAndShapes/js/messages.js
new file mode 120000
index 0000000..1230000
--- /dev/null
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/messages.js
@@ -0,0 +1 @@
+messages.es.js \ No newline at end of file
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/messages.json b/examples/6_Maths_matchingAnglesAndShapes/js/messages.json
deleted file mode 120000
index 0c2aab1..0000000
--- a/examples/6_Maths_matchingAnglesAndShapes/js/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-messages.es.json \ No newline at end of file
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/messages.pot b/examples/6_Maths_matchingAnglesAndShapes/js/messages.pot
index 8333a97..b0e7268 100644
--- a/examples/6_Maths_matchingAnglesAndShapes/js/messages.pot
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/messages.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-28 14:43+0100\n"
+"POT-Creation-Date: 2010-03-02 23:40+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,6 +17,46 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+#: ../../../js/ui.kHeader.js:69
+msgctxt "$.ui.kHeader"
+msgid "Lesson Plan"
+msgstr ""
+
+#: ../../../js/ui.kHeader.js:77
+msgctxt "$.ui.kHeader"
+msgid "Teacher's Note"
+msgstr ""
+
+#: ../../../js/ui.kFooter.js:199
+msgctxt "$.ui.kFooter"
+msgid "Score"
+msgstr ""
+
+#: ../../../js/ui.kFooter.js:204
+msgctxt "$.ui.kFooter"
+msgid "Total"
+msgstr ""
+
+#: ../../../js/ui.kFooter.js:217
+msgctxt "$.ui.kFooter"
+msgid "Timer"
+msgstr ""
+
+#: ../../../js/ui.kFooter.js:241
+msgctxt "$.ui.kFooter"
+msgid "Play Again"
+msgstr ""
+
+#: ../../../js/ui.kFooter.js:256
+msgctxt "$.ui.kFooter"
+msgid "Pause"
+msgstr ""
+
+#: ../../../js/ui.kFooter.js:271
+msgctxt "$.ui.kFooter"
+msgid "Start"
+msgstr ""
+
#: lesson.js:61
msgid "Acute-Angle"
msgstr ""
@@ -69,7 +109,7 @@ msgstr ""
msgid "Maths: Matching Angles with Shapes"
msgstr ""
-#: lesson.js:100 lesson.js:122
+#: lesson.js:107
#, python-format
msgid ""
"You have completed the game in <span class=\"specialText\">%d</span> clicks "
@@ -80,14 +120,14 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: lesson.js:104 lesson.js:126
+#: lesson.js:111
#, python-format
msgid "<span class=\"specialText\">%d</span> minute and "
msgid_plural "<span class=\"specialText\">%d</span> minutes and "
msgstr[0] ""
msgstr[1] ""
-#: lesson.js:108 lesson.js:130
+#: lesson.js:115
#, python-format
msgid "<span class=\"specialText\">%d</span> second."
msgid_plural "<span class=\"specialText\">%d</span> seconds."
diff --git a/examples/6_Maths_matchingAnglesAndShapes/js/mo2js.py b/examples/6_Maths_matchingAnglesAndShapes/js/mo2js.py
index b093202..f2804eb 100755
--- a/examples/6_Maths_matchingAnglesAndShapes/js/mo2js.py
+++ b/examples/6_Maths_matchingAnglesAndShapes/js/mo2js.py
@@ -4,56 +4,68 @@ import codecs
import gettext
import json
-# To deal with keys that occur in more than one place and have a
-# different translation, gettext uses contexts and the
-# pgettext(context, msg) call. This would fit well with what we
-# are trying to do.
-# gettext uses a hack: the context and msg are concatenated into
-# one string with an unprintable character between them, '\004'.
-# A lot of gettext tools can then be oblivious to contexts.
-#
-# The problem however is that xgettext (to extract the strings)
-# doesn't support pgettext when used with --language=Python.
-#
-# Two possibilities:
-# 1. we roll our own xgettext for javascript (starting from e.g. the
-# jslint parser). The code below should be adapted to recognise
-# the '\004' character and extract the context.
-# 2. we abandon using contexts and combine the context and msg into
-# one string. e.g. '$.ui.kFooter.Play Again'
+# TBD: generate $.i18n.choose_pluralized_msg. Similar to how python
+# gettext does this.
-# Other remarks:
-# 1. If there is no context specified, we should not use 'default'
-# as context, because that context might already be used.
-# We should restructure the $.i18n.<lang> dict, e.g.:
-# $.i18n.<lang> =
-# { strings = { 'key': 'val', ...},
-# contextualized_strings = { context1 = { 'key' : 'val', ...},
-# context2 = { 'key' : 'val', ...}}};
-# 2. We should rename messages.<lang>.json to messages.<lang>.js
-# 3. In lesson.html we should refer to messages.js, which is a link to
-# one of the messages.<lang>.js
+def context_and_key(key):
+ """Return a tuple containing the context (or None) and the message
+ key."""
+ # A context, if present, is prepended to the key, with a \x04
+ # character in between.
+ (context, separator, k) = key.partition(u'\x04')
+ if (separator != ''):
+ return (context, k)
+ else:
+ return (None, key)
+
+def group_pluralized_forms(dict):
+ """Return a dictionary where the pluralized forms from dict are
+ grouped. Elements of the form
+ (msg, i) -> tr1
+ ...
+ (msg, j) -> trn
+ are grouped into:
+ msg -> [tr1, ..., trn]
+ """
+ result = {}
+ keys = dict.keys()
+ keys.sort()
+ for k in keys:
+ translation = dict[k]
+ if type(k) is tuple:
+ # A pluralized form k = (msg, n)
+ k = k[0]
+ if k not in result:
+ result[k] = []
+ result[k].append(translation)
+ else:
+ result[k] = translation
+ return result
+
+def path(key):
+ """Return the path in the dictionary for key"""
+ (context, key) = context_and_key(key)
+ if context is not None:
+ return ['contextualized_strings', context, key]
+ else:
+ return ['strings', key]
+
+def store_translation(dictionary, key, translation):
+ p = path(key)
+ while len(p) > 1:
+ x = p.pop(0)
+ if x not in dictionary:
+ dictionary[x] = {}
+ dictionary = dictionary[x]
+ dictionary[p[0]] = translation
def gettext_json(fp, indent = False):
- import gettext
- import json
- try:
- tr = gettext.GNUTranslations(fp)
- keys = tr._catalog.keys()
- keys.sort()
- ret = {}
- for k in keys:
- v = tr._catalog[k]
- if type(k) is tuple:
- # plural: k = (key, n)
- if k[0] not in ret:
- ret[k[0]] = []
- ret[k[0]].append(v)
- else:
- ret[k] = v
- return json.dumps(ret, ensure_ascii = False, indent = indent)
- except IOError:
- return None
+ result = {}
+ tr = gettext.GNUTranslations(fp)
+ dictionary = group_pluralized_forms(tr._catalog)
+ for k, v in group_pluralized_forms(tr._catalog).items():
+ store_translation(result, k, v)
+ return json.dumps(result, ensure_ascii = False, indent = indent)
def usage(argv0):
print 'Usage:'
@@ -67,8 +79,7 @@ if __name__ == '__main__':
[lang, mo, js] = sys.argv[1:]
f = codecs.open(js, encoding='utf-8', mode='w+')
lang = sys.argv[1]
- f.write('$.i18n.%s = {};\n' % lang);
- f.write('$.i18n.%s.strings =\n' % lang);
+ f.write('$.i18n.%s =\n' % lang);
f.write(gettext_json(open(mo, 'r'), True))
f.write(';\n');
f.write('$.i18n.setLocale(\'%s\');\n' % lang);