UNPKG

jsxgettext-andris

Version:

Extracts gettext strings from JavaScript, EJS, Jade, Jinja and Handlebars files. A fork of https://github.com/zaach/jsxgettext

136 lines (116 loc) 4.19 kB
"use strict"; // Turn handlebars helper calls into javascript-syntax functions. // Also comment blocks are turned into javascript comments. function parseHandlebars(str, recurse) { // Using regexes for parsing, ooooh yeeeahhh! // Short comments: {{! this is a comment }} var shortCommentRE = /\{\{\!(.*?)\}\}/; // Long comments: {{!-- this comment has {{markup}} in it --}} var longCommentRE = /\{\{\!--(.*?)--\}\}/; // Block helpers: {{#helper}}template content{{/helper}} var blockHelperStartRE = /\{\{#(translate)?\}\}/; var blockHelperEndRE = /\{\{\/(translate)\}\}/; // Function helpers: {{ helper value }} or {{ helper "some string" }} var singleQuotedStringWithEscapes = "'(([^']*?(\\\\')?)+)'"; var doubleQuotedStringWithEscapes = '"(([^"]*?(\\\\")?)+)"'; var funcHelperRE = new RegExp("\\{\\{\\s*(\\w+)\\s+((\\w+)|(" + singleQuotedStringWithEscapes + ")|(" + doubleQuotedStringWithEscapes + "))\\s*\\}\\}"); // an unescaped double quote starts with anything but an escape (\) or nothing var unescapedDoubleQuote = /([^\\])"|^"/g; var buf = []; var tempBuf; var match = null; function addComment(comment) { buf.push("//"); buf.push(comment); buf.push("\n"); } function escapeQuotes(str) { return str.replace(unescapedDoubleQuote, function (match, group) { var prefix = group || ''; return prefix + '\\"'; }); } while (str.length) { // Find the earliest match of any type of tag in the string. match = str.match(shortCommentRE); if (match) { match.type = 'comment'; } var nextMatch = str.match(longCommentRE); if (nextMatch) { if (!match || nextMatch.index < match.index) { match = nextMatch; match.type = 'comment'; } } nextMatch = str.match(blockHelperStartRE); if (nextMatch) { if (!match || nextMatch.index < match.index) { match = nextMatch; match.type = 'block'; } } nextMatch = str.match(funcHelperRE); if (nextMatch) { if (!match || nextMatch.index < match.index) { match = nextMatch; match.type = 'func'; } } if (!match) { if (recurse) buf.push(str.replace(/\n/g, '\\n')); break; } else if (recurse) { buf.push(str.substring(0, match.index).replace(/\n/g, '\\n')); } str = str.substring(match.index + match[0].length); // Translate the match into an appropriate chunk of javascript. if (match.type === 'comment') { // Template comment => javascript comment match[1].split("\n").forEach(addComment); } else if (match.type === 'block') { if (recurse) buf.push('" + '); // Template block helper => javascript function call var helperName = match[1]; buf.push(helperName); buf.push('("'); tempBuf = []; var endMatch = str.match(blockHelperEndRE); while (endMatch && endMatch[1] !== helperName) { var skipTo = endMatch.index + endMatch[0].length; tempBuf.push(str.substring(0, skipTo)); str = str.substring(skipTo); endMatch = str.match(blockHelperEndRE); } if (endMatch) { tempBuf.push(str.substring(0, endMatch.index)); str = str.substring(endMatch.index + endMatch[0].length); } else { tempBuf.push(str); str = ''; } var result = parseHandlebars(escapeQuotes(tempBuf.join('')), true); buf.push(result); buf.push('")\n'); if (recurse) buf.push(' + "'); } else if (match.type === 'func') { if (recurse) buf.push('" + '); // Template function helper => javascript function call buf.push(match[1]); buf.push('('); buf.push(match[2]); buf.push(')\n'); if (recurse) buf.push(' + "'); } } return buf.join(''); } // generate extracted strings file from Handlebars/Mustache templates exports.handlebars = function Handlebars(hbSources, options) { Object.keys(hbSources).forEach(function (filename) { hbSources[filename] = parseHandlebars(hbSources[filename]); }); return [hbSources, options]; };