diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | jasmine.json | 3 | ||||
-rw-r--r-- | m4/eos-i18n-extras.m4 | 41 | ||||
-rw-r--r-- | test/Makefile.am.inc | 6 | ||||
-rw-r--r-- | test/tools/test.html | 20 | ||||
-rw-r--r-- | test/tools/testHtmlExtractor.js | 30 | ||||
-rw-r--r-- | tools/Makefile.am.inc | 2 | ||||
-rwxr-xr-x | tools/eos-html-extractor | 64 |
8 files changed, 166 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am index 0a918ac..24a7eff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -302,8 +302,9 @@ include $(top_srcdir)/tools/Makefile.am.inc # # # INSTALLED M4 MACROS # # # m4dir = ${datadir}/aclocal -m4_DATA = \ +dist_m4_DATA = \ m4/eos-coverage.m4 \ + m4/eos-i18n-extras.m4 \ $(NULL) # # # TESTS # # # diff --git a/jasmine.json b/jasmine.json index 9c7b40c..3c3e468 100644 --- a/jasmine.json +++ b/jasmine.json @@ -4,7 +4,8 @@ "spec_files": [ "test/endless", "test/webhelper", - "test/tools/eos-application-manifest" + "test/tools/eos-application-manifest", + "test/tools/testHtmlExtractor.js" ], "exclude": [ "test/webhelper/testTranslate.js", diff --git a/m4/eos-i18n-extras.m4 b/m4/eos-i18n-extras.m4 new file mode 100644 index 0000000..629bc73 --- /dev/null +++ b/m4/eos-i18n-extras.m4 @@ -0,0 +1,41 @@ +dnl Copyright 2013-2015 Endless Mobile, Inc. +dnl +dnl Macro to define translation rules for HTML files +dnl Usage: EOS_DEFINE_I18N_RULES (no arguments) +dnl +dnl Usage in Makefile: +dnl HTML_I18N_RULES: +dnl Just include @HTML_I18N_RULES@ and then for each file.html that has +dnl internationalizable values (tags with name="translatable"), put +dnl file.html.dummy.c in your po/POTFILES.in file. Also make sure the dummy file +dnl gets made by putting it in all-am or noinst_DATA. +dnl JSON_I18N_RULES: +dnl Same as HTML_I18N_RULES, but scans file.json for keys ending with an +dnl underscore, and puts those keys' values in file.json.dummy.c. +dnl +dnl Don't forget to add --directory=$(top_builddir) to XGETTEXT_OPTIONS in +dnl po/Makevars, since xgettext by default only looks for the files listed in +dnl POTFILES.in in the source tree, not in the build tree. + +AC_DEFUN([EOS_DEFINE_I18N_RULES], +[ + m4_pattern_allow([AM_V_GEN]) dnl Otherwise the variable is not allowed + AC_REQUIRE([AC_PROG_MKDIR_P]) + HTML_I18N_RULES=' +%.html.dummy.c: %.html + $(AM_V_GEN)$(MKDIR_P) [$](@D) && \ + eos-html-extractor $< $(top_srcdir) >[$]@ +' + + AC_SUBST([HTML_I18N_RULES]) + AM_SUBST_NOTMAKE([HTML_I18N_RULES]) + + JSON_I18N_RULES=' +%.json.dummy.c: %.json + $(AM_V_GEN)$(MKDIR_P) [$](@D) && \ + eos-json-extractor $< $(top_srcdir) >[$]@ +' + + AC_SUBST([JSON_I18N_RULES]) + AM_SUBST_NOTMAKE([JSON_I18N_RULES]) +]) diff --git a/test/Makefile.am.inc b/test/Makefile.am.inc index 842e8e8..f541a5b 100644 --- a/test/Makefile.am.inc +++ b/test/Makefile.am.inc @@ -43,6 +43,7 @@ EXTRA_DIST += \ javascript_tests = \ test/tools/eos-application-manifest/testInit.js \ + test/tools/testHtmlExtractor.js \ test/webhelper/testTranslate.js \ test/webhelper/testTranslate2.js \ test/webhelper/testWebActions.js \ @@ -51,7 +52,10 @@ javascript_tests = \ test/endless/testCustomContainer.js \ test/endless/testTopbarNavButton.js \ $(NULL) -EXTRA_DIST += $(javascript_tests) +EXTRA_DIST += \ + $(javascript_tests) \ + test/tools/test.html \ + $(NULL) # Run tests when running 'make check' TESTS = \ diff --git a/test/tools/test.html b/test/tools/test.html new file mode 100644 index 0000000..4dfda70 --- /dev/null +++ b/test/tools/test.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html dir="ltr" lang="en-US" class="no-js"> + <head> + <meta charset="utf-8"> + <title><span name="translatable">Finance Builder</span></title> + <meta name="description" content="Finance Builder"> + <meta name="author" content="Endless Mobile"> + </head> + <body> + <section id="choose" class="section"> + <!-- TRANSLATORS: This is a test of UTF-8 encoded characters --> + <div class="Intro"><span name="translatable">My Bü∂get</span></div> + <div class="subtitle"><span name="translatable">Choose a template</span></div> + <div id="mi-slider" class="mi-slider"> + <nav id="finance-nav"> + </nav> + </div> + </section> + </body> +</html> diff --git a/test/tools/testHtmlExtractor.js b/test/tools/testHtmlExtractor.js new file mode 100644 index 0000000..4f46706 --- /dev/null +++ b/test/tools/testHtmlExtractor.js @@ -0,0 +1,30 @@ +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; + +const EXPECTED_OUTPUT = '#line 5 "test/tools/test.html"\n\ +_("Finance Builder");\n\ +#line 12 "test/tools/test.html"\n\ +// TRANSLATORS: This is a test of UTF-8 encoded characters\n\ +_("My Bü∂get");\n\ +#line 13 "test/tools/test.html"\n\ +_("Choose a template");\n'; + +describe('eos-html-extractor', function () { + it('works correctly at a minimum', function () { + let srcdir = GLib.getenv('TOP_SRCDIR'); + if (!srcdir) + srcdir = '.'; + let executable = GLib.build_filenamev([srcdir, + 'tools/eos-html-extractor']); + let operand = GLib.build_filenamev([srcdir, 'test/tools/test.html']); + let process = new Gio.Subprocess({ + argv: [executable, operand, srcdir], + flags: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_MERGE, + }); + process.init(null); + let [success, stdout] = process.communicate_utf8(null, null); + expect(process.get_if_exited()).toBeTruthy(); + expect(process.get_exit_status()).toBe(0); + expect(stdout).toEqual(EXPECTED_OUTPUT); + }); +}); diff --git a/tools/Makefile.am.inc b/tools/Makefile.am.inc index 5c53d72..8f0015c 100644 --- a/tools/Makefile.am.inc +++ b/tools/Makefile.am.inc @@ -3,6 +3,7 @@ bin_SCRIPTS = \ tools/eos-application-manifest/eos-application-manifest \ tools/eos-json-extractor/eos-json-extractor \ + tools/eos-html-extractor \ $(NULL) # Use the following script to replace $datadir inside the script, as suggested @@ -29,6 +30,7 @@ CLEANFILES += \ EXTRA_DIST += \ tools/eos-application-manifest/eos-application-manifest.in \ tools/eos-json-extractor/eos-json-extractor.in \ + tools/eos-html-extractor \ $(NULL) commandsdir = $(libexecdir)/eos-application-manifest/commands diff --git a/tools/eos-html-extractor b/tools/eos-html-extractor new file mode 100755 index 0000000..c17d131 --- /dev/null +++ b/tools/eos-html-extractor @@ -0,0 +1,64 @@ +#!/usr/bin/env python +''' +Created on July 19, 2013 + +@author: Sebastian +''' +# This scraper depends on the BeautifulSoup4 module, make sure +# it's installed by running the following: +# apt-get install python-bs4 +import os, re, sys, urllib +from bs4 import BeautifulSoup +from HTMLParser import HTMLParser + +# Parser that adds line numbers to the HTML strings that need translating +class TranslatableHTMLParser(HTMLParser): + def handle_data(self, data): + if data in translatable_strings: + # Determine if comment should be included + most_recent_comment = comments_with_line_numbers[(len(comments_with_line_numbers))-1] + comment_string = most_recent_comment[0] + comment_line = most_recent_comment[1] + code_line = HTMLParser.getpos(self)[0] + # Comment takes up at least one line by default (hence the +1) + comment_length = len(re.findall(r"\n", comment_string)) + 1 + optional_comment = "" + # If the comment immediately preceded this string, include it + if comment_line + comment_length == code_line: + optional_comment = " ".join(comment_string.split()) + all_translatable_data.append((data.strip(), code_line, optional_comment)) + + def handle_comment(self, comment): + comments_with_line_numbers.append((comment, HTMLParser.getpos(self)[0])) + +# Ensure proper usage +if len(sys.argv) != 3: + print("Usage:") + print(" html_extractor.py <input-file> <top-srcdir>") + sys.exit(1) + +# Path from current directory to top-level app directory +html_file = sys.argv[1] +top_dir = sys.argv[2] +final_path = os.path.relpath(html_file, top_dir) + +# Create the BeautifulSoup HTML-parsing object +page = urllib.urlopen(urllib.pathname2url(html_file)).read() +soup = BeautifulSoup(page) + +# Extract all translatable strings from that HTML +translatable_divs = soup.find_all(attrs={"name" : "translatable"}) +translatable_strings = map(lambda div: div.contents[0].encode('utf-8'), translatable_divs) + +# Find the line numbers for those strings +all_translatable_data = [] +comments_with_line_numbers = [] +parser = TranslatableHTMLParser() +parser.feed(page) + +# Write out all info about the translatable strings found in this file +for string, line_num, optional_comment in all_translatable_data: + print ("#line " + str(line_num) + " \"" + final_path + "\"") + if optional_comment != "": + print ("// " + optional_comment) + print ("_(\"" + string + "\");") |