typescript pogen

This commit is contained in:
Florian Dold 2016-01-27 01:07:11 +01:00
parent d2f1cb3234
commit 3ecf03a344
5 changed files with 317 additions and 0 deletions

View File

@ -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",

View 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 ""

View 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
View 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);
});

View File

@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
},
"files": [
"pogen.ts"
]
}