aboutsummaryrefslogtreecommitdiff
path: root/pogen
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2016-02-29 18:03:02 +0100
committerFlorian Dold <florian.dold@gmail.com>2016-02-29 18:03:02 +0100
commitc962e9402123900c53967c14cf809ea10576cdb8 (patch)
treee7df9cfdd6fceae30fb99c8ec6be5e07c8b153a8 /pogen
parent30ee3320c788129b258ed8b42f4fc63d28431e2f (diff)
restructure
Diffstat (limited to 'pogen')
-rw-r--r--pogen/.gitignore1
-rw-r--r--pogen/example/messages.po107
-rw-r--r--pogen/example/test.ts53
-rw-r--r--pogen/pogen.ts173
-rw-r--r--pogen/tsconfig.json11
5 files changed, 345 insertions, 0 deletions
diff --git a/pogen/.gitignore b/pogen/.gitignore
new file mode 100644
index 000000000..a6c7c2852
--- /dev/null
+++ b/pogen/.gitignore
@@ -0,0 +1 @@
+*.js
diff --git a/pogen/example/messages.po b/pogen/example/messages.po
new file mode 100644
index 000000000..1addae3f2
--- /dev/null
+++ b/pogen/example/messages.po
@@ -0,0 +1,107 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-01-27 01:51+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"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: example/test.ts:3
+#, csharp-format
+msgid "Hello1, World"
+msgstr ""
+
+#: example/test.ts:4
+#, csharp-format
+msgid "Hello2, World"
+msgstr ""
+
+#: example/test.ts:5
+#, csharp-format
+msgid "Hello3, World"
+msgstr ""
+
+#. This is a comment and should be included
+#: example/test.ts:9
+#, csharp-format
+msgid "Hello4, World"
+msgstr ""
+
+#: example/test.ts:12
+#, csharp-format
+msgid "Hello5, World"
+msgstr ""
+
+#: example/test.ts:13
+#, csharp-format
+msgid "Hello6,{0} World"
+msgstr ""
+
+#. This one has a multi line comment.
+#. It has multiple lines, and a trailing empty line.
+#.
+#: example/test.ts:20
+#, csharp-format
+msgid "Hello7,{0} World{1}"
+msgstr ""
+
+#: example/test.ts:21
+#, csharp-format
+msgid "{0}Hello8,{1} World{2}"
+msgstr ""
+
+#.
+#. This one has a multi line comment.
+#. It has multiple lines, and a leading empty line.
+#: example/test.ts:28
+#, csharp-format
+msgid "Hello9,\" '\" World"
+msgstr ""
+
+#: example/test.ts:32
+#, csharp-format
+msgid ""
+"Hello10\n"
+" ,\" '\" Wo\n"
+" rld"
+msgstr ""
+
+#: example/test.ts:37
+#, csharp-format
+msgid ""
+"Hello11 this is a long long string\n"
+"it will go over multiple lines and in the pofile\n"
+"it should be wrapped and stuff"
+msgstr ""
+
+#. This is a single line comment
+#: example/test.ts:42
+#, csharp-format
+msgid ""
+"Hello12 this is a long long string it will go over multiple lines and in the "
+"pofile it should be wrapped and stuff. asdf asdf asdf asdf asdf asdf asdf asdf "
+"adsf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf "
+"asdf"
+msgstr ""
+
+#: example/test.ts:42
+#, csharp-format
+msgid "This message appears twice"
+msgstr ""
+
+#: example/test.ts:45
+#, csharp-format
+msgid "This message appears twice"
+msgstr ""
+
diff --git a/pogen/example/test.ts b/pogen/example/test.ts
new file mode 100644
index 000000000..2cc15b063
--- /dev/null
+++ b/pogen/example/test.ts
@@ -0,0 +1,53 @@
+declare var i18n: any;
+
+console.log(i18n`Hello1, World`);
+console.log(i18n.foo()`Hello2, World`);
+console.log(i18n.foo()`Hello3, World`);
+
+
+/* This is a comment and should be included */
+console.log(i18n().foo()`Hello4, World`);
+
+
+console.log(i18n.foo`Hello5, World`);
+console.log(i18n.foo`Hello6,${123} World`);
+
+/*
+This one has a multi line comment.
+It has multiple lines, and a trailing empty line.
+
+*/
+console.log(/*lol*/i18n.foo`Hello7,${123} World${42}`);
+
+
+i18n.plural()
+
+console.log(i18n`${"foo"}Hello8,${123} World${42}`);
+
+/*
+
+This one has a multi line comment.
+It has multiple lines, and a leading empty line.
+*/
+console.log(i18n`Hello9," '" World`);
+
+// Comments with space inbetween do not count
+
+console.log(i18n`Hello10
+ ," '" Wo
+ rld`);
+
+
+console.log(i18n`Hello11 this is a long long string
+it will go over multiple lines and in the pofile
+it should be wrapped and stuff`);
+
+// This is a single line comment
+console.log(i18n`Hello12 this is a long long string it will go over multiple lines and in the pofile it should be wrapped and stuff. asdf asdf asdf asdf asdf asdf asdf asdf adsf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf`);
+
+
+
+// First occurence
+console.log(i18n`This message appears twice`);
+// Second occurence
+console.log(i18n`This message appears twice`);
diff --git a/pogen/pogen.ts b/pogen/pogen.ts
new file mode 100644
index 000000000..77f7ea3dc
--- /dev/null
+++ b/pogen/pogen.ts
@@ -0,0 +1,173 @@
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
+ */
+
+
+/**
+ * Generate .po file from list of source files.
+ *
+ * Note that duplicate message IDs are NOT merged, to get the same output as
+ * you would from xgettext, just run msguniq.
+ */
+
+/// <reference path="../lib/decl/node.d.ts" />
+
+"use strict";
+
+import {readFileSync} from "fs";
+import {execSync} from "child_process";
+import * as ts from "typescript";
+
+
+function wordwrap(str: string, width: number = 80): string[] {
+ var regex = '.{1,' + width + '}(\\s|$)|\\S+(\\s|$)';
+ return str.match(RegExp(regex, 'g'));
+}
+
+export function processFile(sourceFile: ts.SourceFile) {
+ processNode(sourceFile);
+ let lastTokLine = 0;
+ let preLastTokLine = 0;
+
+ function getHeadName(node: ts.Node): string {
+ switch (node.kind) {
+ case ts.SyntaxKind.Identifier:
+ return (<ts.Identifier>node).text;
+ case ts.SyntaxKind.CallExpression:
+ case ts.SyntaxKind.PropertyAccessExpression:
+ return getHeadName((<any>node).expression);
+ }
+ }
+
+ function getTemplate(node: ts.Node): string {
+ switch (node.kind) {
+ case ts.SyntaxKind.FirstTemplateToken:
+ return (<any>node).text;
+ case ts.SyntaxKind.TemplateExpression:
+ let te = <ts.TemplateExpression>node;
+ let textFragments = [te.head.text];
+ for (let tsp of te.templateSpans) {
+ textFragments.push(`%${(textFragments.length-1)/2+1}$s`);
+ textFragments.push(tsp.literal.text);
+ }
+ return textFragments.join('');
+ default:
+ return "(pogen.ts: unable to parse)";
+ }
+ }
+
+ function getComment(node: ts.Node, lc): string {
+ let lastComments;
+ for (let l = preLastTokLine; l < lastTokLine; l++) {
+ let pos = ts.getPositionOfLineAndCharacter(sourceFile, l, 0);
+ let comments = ts.getTrailingCommentRanges(sourceFile.text, pos);
+ if (comments) {
+ lastComments = comments;
+ }
+ }
+ if (!lastComments) {
+ return;
+ }
+ let candidate = lastComments[lastComments.length-1];
+ let candidateEndLine = ts.getLineAndCharacterOfPosition(sourceFile, candidate.end).line;
+ if (candidateEndLine != lc.line - 1) {
+ return;
+ }
+ let text = sourceFile.text.slice(candidate.pos, candidate.end);
+ switch (candidate.kind) {
+ case ts.SyntaxKind.SingleLineCommentTrivia:
+ // Remove comment leader
+ text = text.replace(/^[/][/]\s*/, "");
+ break;
+ case ts.SyntaxKind.MultiLineCommentTrivia:
+ // Remove comment leader and trailer,
+ // handling white space just like xgettext.
+ text = text
+ .replace(/^[/][*](\s*?\n|\s*)?/, "")
+ .replace(/(\n[ \t]*?)?[*][/]$/, "");
+ break;
+ }
+ return text;
+ }
+
+ function processNode(node: ts.Node) {
+ switch (node.kind) {
+ case ts.SyntaxKind.TaggedTemplateExpression:
+ let lc = ts.getLineAndCharacterOfPosition(sourceFile, node.pos);
+ if (lc.line != lastTokLine) {
+ preLastTokLine = lastTokLine;
+ lastTokLine = lc.line;
+ }
+ let tte = <ts.TaggedTemplateExpression>node;
+ let headName = getHeadName(tte.tag);
+ let comment = getComment(tte, lc);
+ let tpl = getTemplate(tte.template).replace(/"/g, '\\"');
+ // Do escaping, wrap break at newlines
+ let parts = tpl
+ .match(/(.*\n|.+$)/g)
+ .map((x) => x.replace(/\n/g, '\\n'))
+ .map((p) => wordwrap(p))
+ .reduce((a,b) => a.concat(b));
+ if (comment) {
+ for (let cl of comment.split('\n')) {
+ console.log(`#. ${cl}`);
+ }
+ }
+ console.log(`#: ${sourceFile.fileName}:${lc.line+1}`);
+ console.log(`#, c-format`);
+ if (parts.length == 1) {
+ console.log(`msgid "${parts[0]}"`);
+ } else {
+ console.log(`msgid ""`);
+ for (let p of parts) {
+ console.log(`"${p}"`);
+ }
+ }
+ console.log(`msgstr ""`);
+ console.log();
+ break;
+ }
+
+ ts.forEachChild(node, processNode);
+ }
+}
+
+const fileNames = process.argv.slice(2);
+
+console.log(
+`# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\\n"
+"Report-Msgid-Bugs-To: \\n"
+"POT-Creation-Date: ${execSync("date '+%F %H:%M%z'").toString().trim()}\\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"
+"Language: \\n"
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=UTF-8\\n"
+"Content-Transfer-Encoding: 8bit\\n"`);
+console.log()
+
+fileNames.forEach(fileName => {
+ let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true);
+ processFile(sourceFile);
+});
diff --git a/pogen/tsconfig.json b/pogen/tsconfig.json
new file mode 100644
index 000000000..3d2b2c002
--- /dev/null
+++ b/pogen/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es5",
+ "noImplicitAny": false,
+ "sourceMap": false
+ },
+ "files": [
+ "pogen.ts"
+ ]
+}