typescript pogen
This commit is contained in:
parent
d2f1cb3234
commit
3ecf03a344
@ -15,6 +15,7 @@
|
||||
"devDependencies": {
|
||||
"better-assert": "^1.0.2",
|
||||
"del": "^2.2.0",
|
||||
"esprima": "^2.7.1",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-typescript": "^2.10.0",
|
||||
"gulp-zip": "^3.1.0",
|
||||
|
97
extension/pogen/example/messages.po
Normal file
97
extension/pogen/example/messages.po
Normal file
@ -0,0 +1,97 @@
|
||||
# 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:05+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=CHARSET\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 ""
|
||||
|
42
extension/pogen/example/test.ts
Normal file
42
extension/pogen/example/test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
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}`);
|
||||
console.log(i18n.foo`${"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`);
|
166
extension/pogen/pogen.ts
Normal file
166
extension/pogen/pogen.ts
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/// <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}}`);
|
||||
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:
|
||||
text = text.replace(/^[/][/]\s*/, "");
|
||||
break;
|
||||
case ts.SyntaxKind.MultiLineCommentTrivia:
|
||||
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, '\\"');
|
||||
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(`#, csharp-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=CHARSET\\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);
|
||||
});
|
11
extension/pogen/tsconfig.json
Normal file
11
extension/pogen/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false
|
||||
},
|
||||
"files": [
|
||||
"pogen.ts"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user