diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-11-16 04:02:02 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-11-16 04:02:02 +0100 |
commit | a56210dfc9a40a32a2025eb462eead436ce180bb (patch) | |
tree | 861f1aad2c36be57bbade6d9e87e378f2f33bc9a | |
parent | af11f34fb52b68c6e68df097c43d594893c60f8d (diff) |
add JSX translation extraction
-rw-r--r-- | pogen/dumpTree.ts | 4 | ||||
-rw-r--r-- | pogen/example/test2.tsx | 16 | ||||
-rw-r--r-- | pogen/pogen.ts | 155 |
3 files changed, 159 insertions, 16 deletions
diff --git a/pogen/dumpTree.ts b/pogen/dumpTree.ts index 6055defba..958c79416 100644 --- a/pogen/dumpTree.ts +++ b/pogen/dumpTree.ts @@ -21,7 +21,7 @@ * @author Florian Dold */ -/// <reference path="../lib/decl/node.d.ts" /> +/// <reference path="../decl/node.d.ts" /> "use strict"; @@ -46,6 +46,6 @@ export function processFile(sourceFile: ts.SourceFile) { const fileNames = process.argv.slice(2); fileNames.forEach(fileName => { - let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true); + let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2016, /*setParentNodes */ true); processFile(sourceFile); }); diff --git a/pogen/example/test2.tsx b/pogen/example/test2.tsx index 08a1deacc..4133f86fb 100644 --- a/pogen/example/test2.tsx +++ b/pogen/example/test2.tsx @@ -1 +1,15 @@ -let y = <div>a{b}c</div> +let x = <i18n.Translate>foo +{bar} {" foo "} baz</i18n.Translate> + + +let y = ( + <i18n.TranslateSwitch> + <i18n.TranslateSingular> + singular form + second line + </i18n.TranslateSingular> + <i18n.TranslatePlural> + plural form + </i18n.TranslatePlural> + </i18n.TranslateSwitch> +); diff --git a/pogen/pogen.ts b/pogen/pogen.ts index a622c9990..1e0467d4e 100644 --- a/pogen/pogen.ts +++ b/pogen/pogen.ts @@ -24,7 +24,7 @@ * @author Florian Dold */ -/// <reference path="../lib/decl/node.d.ts" /> +/// <reference path="../decl/node.d.ts" /> "use strict"; @@ -43,16 +43,6 @@ export function processFile(sourceFile: ts.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: @@ -62,7 +52,7 @@ export function processFile(sourceFile: ts.SourceFile) { let textFragments = [te.head.text]; for (let tsp of te.templateSpans) { textFragments.push(`%${(textFragments.length-1)/2+1}$s`); - textFragments.push(tsp.literal.text); + textFragments.push(tsp.literal.text.replace(/%/g, "%%")); } return textFragments.join(''); default: @@ -178,10 +168,149 @@ export function processFile(sourceFile: ts.SourceFile) { } } } + + interface JsxProcessingContext { + + } + + function getJsxElementPath(node: ts.Node) { + let path; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxOpeningElement: + { + let e = childNode as ts.JsxOpeningElement; + return path = getPath(e.tagName); + } + default: + break; + } + }; + ts.forEachChild(node, process); + return path; + } + + function translateJsxExpression(node: ts.Node, h) { + switch (node.kind) { + case ts.SyntaxKind.StringLiteral: + { + let e = node as ts.StringLiteral; + return e.text; + } + default: + return `%${h[0]++}s`; + } + } + + function trim(s) { + return s.replace(/^[ \n\t]*/, "").replace(/[ \n\t]*$/, ""); + } + + function getJsxContent(node: ts.Node) { + let fragments = []; + let holeNum = [1]; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxText: + { + let e = childNode as ts.JsxText; + let t = e.getText().split("\n").map(trim).join("\n"); + fragments.push(t); + } + case ts.SyntaxKind.JsxOpeningElement: + break; + case ts.SyntaxKind.JsxExpression: + { + let e = childNode as ts.JsxExpression; + fragments.push(translateJsxExpression(e.expression, holeNum)); + break; + } + case ts.SyntaxKind.JsxClosingElement: + break; + default: + console.error("unrecognized syntax in JSX Element", ts.SyntaxKind[childNode.kind]); + break; + } + }; + ts.forEachChild(node, process); + return fragments.join(""); + } + + function getJsxSingular(node: ts.Node) { + let res; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxElement: + { + let path = getJsxElementPath(childNode); + if (arrayEq(path, ["i18n", "TranslateSingular"])) { + res = getJsxContent(childNode); + } + } + default: + break; + } + }; + ts.forEachChild(node, process); + return res; + } + + function getJsxPlural(node: ts.Node) { + let res; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxElement: + { + let path = getJsxElementPath(childNode); + if (arrayEq(path, ["i18n", "TranslatePlural"])) { + res = getJsxContent(childNode); + } + } + default: + break; + } + }; + ts.forEachChild(node, process); + return res; + } function processNode(node: ts.Node) { switch (node.kind) { + case ts.SyntaxKind.JsxElement: + let path = getJsxElementPath(node); + if (arrayEq(path, ["i18n", "Translate"])) { + let content = getJsxContent(node); + let {line} = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); + let comment = getComment(node); + formatMsgComment(line, comment); + formatMsgLine("msgid", content); + console.log(`msgstr[0] ""`); + console.log(); + return; + } + if (arrayEq(path, ["i18n", "TranslateSwitch"])) { + let {line} = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); + let comment = getComment(node); + formatMsgComment(line, comment); + let singularForm = getJsxSingular(node); + if (!singularForm) { + console.error("singular form missing"); + process.exit(1); + } + let pluralForm = getJsxPlural(node); + if (!pluralForm) { + console.error("plural form missing"); + process.exit(1); + } + formatMsgLine("msgid", singularForm); + formatMsgLine("msgid_plural", pluralForm); + console.log(`msgstr[0] ""`); + console.log(`msgstr[1] ""`); + console.log(); + return; + } + break; case ts.SyntaxKind.CallExpression: { // might be i18n.plural(i18n[.X]`...`, i18n[.X]`...`) @@ -254,6 +383,6 @@ msgstr "" console.log() fileNames.forEach(fileName => { - let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true); + let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2016, /*setParentNodes */ true); processFile(sourceFile); }); |