chg: replaced ant with gradle
This commit is contained in:
parent
cee0be52e0
commit
5cbeb9f01d
609 changed files with 87626 additions and 638 deletions
428
modules/jala/util/HopKit/scripts/MessageParser.js
Normal file
428
modules/jala/util/HopKit/scripts/MessageParser.js
Normal file
|
@ -0,0 +1,428 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the ``License'');
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an ``AS IS'' BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
* MessageParser script that extracts all gettext message macros
|
||||
* out of skin files and all calls of gettext functions
|
||||
* (that is "gettext", "ngettext" and "_") out of function
|
||||
* files and directly generates a .pot file from it.
|
||||
* If an argument "-o" is given and it is followed by
|
||||
* a path to a file, the output is written to this file.
|
||||
* Any other argument is interpreted as directory or file
|
||||
* that should be parsed.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
var Message = function(id, pluralId) {
|
||||
this.id = id && String(id);
|
||||
this.pluralId = pluralId && String(pluralId);
|
||||
this.locations = [];
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static method that constructs a message key by
|
||||
* which a message can be identified in the messages map.
|
||||
* @param {String} id The message Id
|
||||
* @param {String} pluralId The plural message Id
|
||||
* @returns The generated message key
|
||||
* @type String
|
||||
*/
|
||||
Message.getKey = function(id, pluralId) {
|
||||
if (id && pluralId) {
|
||||
return id + pluralId;
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Encloses the string passed as argument in quotes
|
||||
* and wraps the string if it is longer than 80 characters.
|
||||
* @param {String} str The string to format
|
||||
* @param {Boolean} wrap If true the message string will be splitted in
|
||||
* parts where each one is max. 80 characters long
|
||||
* @returns The formatted string.
|
||||
* @type String
|
||||
*/
|
||||
Message.formatId = function(str, wrap) {
|
||||
var escapeQuotes = function(s) {
|
||||
return s.replace(/(^|[^\\])"/g, '$1\\"');
|
||||
};
|
||||
|
||||
var len = 80;
|
||||
var buf = new java.lang.StringBuffer();
|
||||
if (wrap == true && str.length > len) {
|
||||
buf.append('""\n');
|
||||
var offset = 0;
|
||||
while (offset < str.length) {
|
||||
buf.append('"');
|
||||
buf.append(escapeQuotes(str.substring(offset, offset += len)));
|
||||
buf.append('"');
|
||||
buf.append("\n");
|
||||
}
|
||||
return buf.toString();
|
||||
} else {
|
||||
buf.append('"');
|
||||
buf.append(escapeQuotes(str));
|
||||
buf.append('"\n');
|
||||
}
|
||||
return buf.toString();
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a new location to this Message instance.
|
||||
* @param {String} filePath The path to the file this message
|
||||
* is located in.
|
||||
* @param {Number} lineNum The line number at which this message
|
||||
* was found at
|
||||
*/
|
||||
Message.prototype.addLocation = function(filePath, lineNum) {
|
||||
this.locations.push(filePath + ":" + lineNum);
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes this Message instance as .po compatible string to
|
||||
* the StringBuffer passed as argument.
|
||||
* @param {java.lang.StringBuffer} buf The StringBuffer instance
|
||||
* to write into
|
||||
*/
|
||||
Message.prototype.write = function(buf) {
|
||||
for (var i=0;i<this.locations.length;i++) {
|
||||
buf.append("#: ");
|
||||
buf.append(this.locations[i]);
|
||||
buf.append("\n");
|
||||
}
|
||||
if (this.id.indexOf("{") > -1
|
||||
|| (this.pluralId != null && this.pluralId.indexOf("{") > -1)) {
|
||||
buf.append("#, java-format\n");
|
||||
}
|
||||
buf.append('msgid ');
|
||||
buf.append(Message.formatId(this.id));
|
||||
if (this.pluralId != null) {
|
||||
buf.append('msgid_plural ');
|
||||
buf.append(Message.formatId(this.pluralId));
|
||||
buf.append('msgstr[0] ""\nmsgstr[1] ""\n')
|
||||
} else {
|
||||
buf.append('msgstr ""\n')
|
||||
}
|
||||
buf.append("\n");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
var MessageParser = function() {
|
||||
this.messages = {};
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Object containing the accepted function names, currently
|
||||
* supported are "gettext", "ngettext" and "_". This is used
|
||||
* as a lookup map during function file parsing.
|
||||
* @type Object
|
||||
*/
|
||||
MessageParser.FUNCTION_NAMES = {
|
||||
"_": true,
|
||||
"gettext": true,
|
||||
"ngettext": true,
|
||||
"markgettext": true
|
||||
};
|
||||
|
||||
/**
|
||||
* The name of the gettext macro
|
||||
* @type String
|
||||
*/
|
||||
MessageParser.MACRO_NAME = "message";
|
||||
|
||||
/**
|
||||
* The name of the macro attribute that will be interpreted
|
||||
* as gettext attribute.
|
||||
* @type String
|
||||
*/
|
||||
MessageParser.ATTRIBUTE_NAME = MessageParser.MACRO_NAME;
|
||||
|
||||
/**
|
||||
* A regular expression for parsing macros in a skin. The result
|
||||
* of this regular expression contains:
|
||||
* result[1] = macro handler name (can be empty for global macros)
|
||||
* result[2] = macro name
|
||||
* result[3] = the macro's attributes
|
||||
* @type RegExp
|
||||
*/
|
||||
MessageParser.REGEX_MACRO = /<%\s*(?:([\w]+)\.)?([\w]+)\s+([^%]+?)\s*%>/gm;
|
||||
|
||||
/**
|
||||
* A regular expression for parsing the attributes of a macro. The result
|
||||
* of this regular expression contains:
|
||||
* result[1] = attribute name
|
||||
* result[2] = attribute value
|
||||
* @type RegExp
|
||||
*/
|
||||
MessageParser.REGEX_PARAM = /([\w]*)\s*=\s*["'](.*?)["']\s*(?=\w+=|$)/gm;
|
||||
|
||||
/**
|
||||
* Calculates the line number in the string passed as argument
|
||||
* at which the specified index position is located.
|
||||
* @param {String} str The source string
|
||||
* @param {Number} idx The index position to get the line number for.
|
||||
* @returns The line number of the index position in the source string.
|
||||
* @type Number
|
||||
*/
|
||||
MessageParser.getLineNum = function(str, idx) {
|
||||
return str.substring(0, idx).split(/.*(?:\r\n|\n\r|\r|\n)/).length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the file passed as argument. If the file
|
||||
* is a directory, this method recurses down the directory
|
||||
* tree and parses all skin and function files.
|
||||
* @param {java.io.File} file The file or directory to start at.
|
||||
* @param {String} encoding The encoding to use
|
||||
*/
|
||||
MessageParser.prototype.parse = function(file, encoding) {
|
||||
if (file.isDirectory()) {
|
||||
var list = file.list();
|
||||
for (var i=0;i<list.length;i++) {
|
||||
this.parse(new java.io.File(file, list[i]), encoding);
|
||||
}
|
||||
} else {
|
||||
var fName, dotIdx;
|
||||
fName = file.getName();
|
||||
if ((dotIdx = fName.lastIndexOf(".")) > -1) {
|
||||
switch (String(fName.substring(dotIdx+1))) {
|
||||
case "skin":
|
||||
print("Parsing skin file " + file.getAbsolutePath() + "...");
|
||||
this.parseSkinFile(file, encoding);
|
||||
break;
|
||||
case "hac":
|
||||
case "js":
|
||||
print("Parsing function file " + file.getAbsolutePath() + "...");
|
||||
this.parseFunctionFile(file, encoding);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
MessageParser.prototype.toString = function() {
|
||||
return "[Jala Message Parser]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses a .js file and creates Message instances for all
|
||||
* calls of "gettext", "ngettext", "markgettext" and "_".
|
||||
* @param {java.io.File} file The function file to parse
|
||||
* @param {String} encoding The encoding to use
|
||||
*/
|
||||
MessageParser.prototype.parseFunctionFile = function(file, encoding) {
|
||||
var fis = new java.io.FileInputStream(file);
|
||||
var isr = new java.io.InputStreamReader(fis, encoding || "UTF-8");
|
||||
var reader = new java.io.BufferedReader(isr);
|
||||
var tokenizer = new java.io.StreamTokenizer(reader);
|
||||
var messages = [], stack = [];
|
||||
var c;
|
||||
while ((c = tokenizer.nextToken()) != java.io.StreamTokenizer.TT_EOF) {
|
||||
switch (c) {
|
||||
case java.io.StreamTokenizer.TT_WORD:
|
||||
if (MessageParser.FUNCTION_NAMES[tokenizer.sval] == true) {
|
||||
stack.push({name: tokenizer.sval, lineNr: tokenizer.lineno()});
|
||||
} else if (stack.length > 0) {
|
||||
// it's something else than a string argument inside a gettext method call
|
||||
// so finalize the argument parsing here as we aren't interested in that
|
||||
messages.push(stack.pop());
|
||||
}
|
||||
break;
|
||||
case java.io.StreamTokenizer.TT_NUMBER:
|
||||
break;
|
||||
default:
|
||||
if (stack.length > 0) {
|
||||
if ("\u0028".charCodeAt(0) == c) {
|
||||
// start of arguments (an opening bracket)
|
||||
stack[stack.length-1].args = [];
|
||||
} else if ("\u0029".charCodeAt(0) == c) {
|
||||
// end of arguments (a closing bracket)
|
||||
messages.push(stack.pop());
|
||||
} else if ("\u0022".charCodeAt(0) == c || "\u0027".charCodeAt(0) == c) {
|
||||
// a quoted string argument
|
||||
stack[stack.length-1].args.push(tokenizer.sval);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (messages.length > 0) {
|
||||
var msgParam, key, msg;
|
||||
for (var i=0;i<messages.length;i++) {
|
||||
msgParam = messages[i];
|
||||
if (msgParam.args && msgParam.args.length > 0) {
|
||||
key = Message.getKey(msgParam.args[0]);
|
||||
if (!(msg = this.messages[key])) {
|
||||
this.messages[key] = msg = new Message(msgParam.args[0], msgParam.args[1]);
|
||||
}
|
||||
if (!msg.pluralId && msgParam.args.length > 1) {
|
||||
msg.pluralId = msgParam.args[1];
|
||||
}
|
||||
msg.addLocation(file.getAbsolutePath(), msgParam.lineNr);
|
||||
}
|
||||
}
|
||||
}
|
||||
fis.close();
|
||||
isr.close();
|
||||
reader.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses a skin file and creates Message instances for
|
||||
* all macros which name is either "message" or
|
||||
* that have attributes named "message" and optional
|
||||
* "plural"
|
||||
* @param {java.io.File} file The skin file to parse
|
||||
* @param {String} encoding The encoding to use
|
||||
*/
|
||||
MessageParser.prototype.parseSkinFile = function(file, encoding) {
|
||||
var content = readFile(file.getAbsolutePath(), encoding || "UTF-8");
|
||||
var macro, id, pluralId, params, key;
|
||||
while (macro = MessageParser.REGEX_MACRO.exec(content)) {
|
||||
while (params = MessageParser.REGEX_PARAM.exec(macro[3])) {
|
||||
if (macro[2] == MessageParser.MACRO_NAME) {
|
||||
if (params[1] == "text") {
|
||||
id = params[2];
|
||||
pluralId = null;
|
||||
} else if (params[1] == "plural") {
|
||||
pluralId = params[2];
|
||||
}
|
||||
} else {
|
||||
if (params[1] == MessageParser.ATTRIBUTE_NAME) {
|
||||
id = params[2];
|
||||
pluralId = null;
|
||||
} else if (params[1] == "plural") {
|
||||
pluralId = params[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (id != null) {
|
||||
// create new Message instance or update the existing one
|
||||
key = Message.getKey(id);
|
||||
if (!(msg = this.messages[key])) {
|
||||
this.messages[key] = msg = new Message(id, pluralId, file.getAbsolutePath());
|
||||
}
|
||||
msg.addLocation(file.getAbsolutePath(),
|
||||
MessageParser.getLineNum(content, macro.index));
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prints a standard Header of a .po file
|
||||
* FIXME: why the hell is Plural-Forms ignored in poEdit?
|
||||
* @see http://drupal.org/node/17564
|
||||
*/
|
||||
MessageParser.prototype.getPotString = function() {
|
||||
var buf = new java.lang.StringBuffer();
|
||||
buf.append('# SOME DESCRIPTIVE TITLE.\n');
|
||||
buf.append('# Copyright (C) YEAR THE PACKAGE\'S COPYRIGHT HOLDER\n');
|
||||
buf.append('# This file is distributed under the same license as the PACKAGE package.\n');
|
||||
buf.append('# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n');
|
||||
buf.append('#\n');
|
||||
buf.append('#, fuzzy\n');
|
||||
buf.append('msgid ""\n');
|
||||
buf.append('msgstr ""\n');
|
||||
buf.append('"Project-Id-Version: PACKAGE VERSION\\n"\n');
|
||||
buf.append('"Report-Msgid-Bugs-To: \\n"\n');
|
||||
var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mmZ");
|
||||
buf.append('"POT-Creation-Date: ' + sdf.format(new java.util.Date()) + '\\n"\n');
|
||||
buf.append('"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"\n');
|
||||
buf.append('"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"\n');
|
||||
buf.append('"Language-Team: LANGUAGE <LL@li.org>\\n"\n');
|
||||
buf.append('"MIME-Version: 1.0\\n"\n');
|
||||
buf.append('"Content-Type: text/plain; charset=utf-8\\n"\n');
|
||||
buf.append('"Content-Transfer-Encoding: 8bit\\n"\n');
|
||||
buf.append('"Plural-Forms: nplurals=2; plural=(n != 1);\\n"\n');
|
||||
buf.append('\n');
|
||||
|
||||
// sort all messages by their singular key
|
||||
var keys = [];
|
||||
for (var i in this.messages) {
|
||||
keys[keys.length] = this.messages[i].id;
|
||||
}
|
||||
keys.sort();
|
||||
// add all the messages
|
||||
for (var i=0;i<keys.length;i++) {
|
||||
this.messages[keys[i]].write(buf);
|
||||
}
|
||||
return buf.toString();
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the parsed contents into the file passed as argument.
|
||||
* @param {java.io.File} file The file to write to
|
||||
*/
|
||||
MessageParser.prototype.writeToFile = function(file) {
|
||||
var writer = new java.io.FileWriter(file);
|
||||
writer.write(new java.lang.String(this.getPotString().getBytes("UTF-8")));
|
||||
writer.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main script body
|
||||
*/
|
||||
var toParse = [];
|
||||
var arg, outFile, file, fileEncoding;
|
||||
|
||||
for (var i=0;i<arguments.length;i++) {
|
||||
arg = arguments[i];
|
||||
if (arg.indexOf("-o") === 0 && i < arguments.length -1) {
|
||||
outFile = new java.io.File(arguments[i += 1]);
|
||||
} else if (arg.indexOf("-e") === 0 && i < arguments.length -1) {
|
||||
fileEncoding = arguments[i += 1];
|
||||
} else {
|
||||
// add argument to list of files and directories to parse
|
||||
toParse.push(new java.io.File(arg));
|
||||
}
|
||||
}
|
||||
|
||||
// start parsing
|
||||
var parser = new MessageParser();
|
||||
for (var i=0;i<toParse.length;i++) {
|
||||
parser.parse(toParse[i], fileEncoding);
|
||||
}
|
||||
if (outFile != null) {
|
||||
parser.writeToFile(outFile);
|
||||
} else {
|
||||
print(parser.getPotString());
|
||||
}
|
336
modules/jala/util/HopKit/scripts/PoParser.js
Normal file
336
modules/jala/util/HopKit/scripts/PoParser.js
Normal file
|
@ -0,0 +1,336 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the ``License'');
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an ``AS IS'' BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
* A parser script that converts GNU Gettext .po files into plain JavaScript objects
|
||||
* for use with jala.I18n. To run it either start the build script of HopKit
|
||||
* or call it directly using the JavaScript shell of Rhino:
|
||||
* <code>java -cp rhino.jar org.mozilla.javascript.tools.shell.Main PoParser.js <input> <output> [namespace]</code>
|
||||
*
|
||||
* The accepted arguments are:
|
||||
* <ul>
|
||||
* <li><code>input</code>: Either a single .po file or a directory containing multiple files</li>
|
||||
* <li><code>output</code>: The directory where to put the generated message files</li>
|
||||
* <li><code>namespace</code>: An optional namespace in which the generated message object will reside
|
||||
* (eg. if the namespace is called "jala", the messages will be stored in global.jala.messages)</li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new PoParser instance.
|
||||
* @class Instances of this class can generate JavaScript message files out
|
||||
* of GNU Gettext .po files for use with jala.I18n (and possibly other internationalization
|
||||
* environments too).
|
||||
* @param {String} handler An optional namespace where the parsed messages should be stored
|
||||
* @returns A newly created instance of PoParser
|
||||
* @constructor
|
||||
*/
|
||||
var PoParser = function(namespace) {
|
||||
/**
|
||||
* An array containing the parsed messages
|
||||
* @type Array
|
||||
*/
|
||||
this.messages = [];
|
||||
|
||||
/**
|
||||
* The locale key string (eg. "de_AT") of the .po file
|
||||
* @type String
|
||||
*/
|
||||
this.localeKey = null;
|
||||
|
||||
/**
|
||||
* The namespace (optional) where to store the generated messages
|
||||
* @type String
|
||||
*/
|
||||
this.namespace = namespace;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* A regular expression for splitting the contents of a .po file into
|
||||
* single lines
|
||||
* @type RegExp
|
||||
*/
|
||||
PoParser.REGEX_LINES = /\r\n|\r|\n|\u0085|\u2028|\u2029/;
|
||||
|
||||
/**
|
||||
* A regular expression for parsing singular message keys
|
||||
* @type RegExp
|
||||
*/
|
||||
PoParser.REGEX_MSGID = /^\s*msgid(?!_plural)\s+\"(.*)\"\s*$/;
|
||||
|
||||
/**
|
||||
* A regular expression for parsing plural message keys
|
||||
* @type RegExp
|
||||
*/
|
||||
PoParser.REGEX_MSGID_PLURAL = /^\s*msgid_plural\s+\"(.*)\"\s*$/;
|
||||
|
||||
/**
|
||||
* A regular expression for parsing message key continuations
|
||||
* @type RegExp
|
||||
*/
|
||||
PoParser.REGEX_MSG_CONT = /^\s*\"(.*)\"\s*$/;
|
||||
|
||||
/**
|
||||
* A regular expression for parsing a message translation
|
||||
* @type RegExp
|
||||
*/
|
||||
PoParser.REGEX_MSGSTR = /^\s*msgstr(?:\[(\d)\])?\s+\"(.*)\"\s*$/;
|
||||
|
||||
/**
|
||||
* A regular expression used to detect lines other than whitespace
|
||||
* and comments
|
||||
* @type RegExp
|
||||
*/
|
||||
PoParser.REGEX_DATA = /^\s*msg/;
|
||||
|
||||
PoParser.isData = function(str) {
|
||||
return PoParser.REGEX_DATA.test(str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads the file passed as argument, assuming that it is UTF-8 encoded
|
||||
* @param {java.io.File} file The file to read
|
||||
* @returns The contents of the file
|
||||
* @type java.lang.String
|
||||
*/
|
||||
PoParser.readFile = function(file) {
|
||||
var inStream = new java.io.InputStreamReader(new java.io.FileInputStream(file), "UTF-8");
|
||||
var buffer = new java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2048);
|
||||
var read = 0;
|
||||
var r = 0;
|
||||
while ((r = inStream.read(buffer, read, buffer.length - read)) > -1) {
|
||||
read += r;
|
||||
if (read == buffer.length) {
|
||||
// grow input buffer
|
||||
var newBuffer = new java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, buffer.length * 2);
|
||||
java.lang.System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
|
||||
buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
inStream.close();
|
||||
return new java.lang.String(buffer, 0, read);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the PO file passed as argument into the messages array
|
||||
* of this PoParser instance.
|
||||
* @param {java.io.File} file The .po file to parse
|
||||
*/
|
||||
PoParser.prototype.parse = function(file) {
|
||||
// parse the locale key out of the file name
|
||||
var fileName = file.getName();
|
||||
if (!(this.localeKey = fileName.substring(0, fileName.indexOf(".")))) {
|
||||
throw "Invalid PO file name: " + fileName;
|
||||
}
|
||||
|
||||
// read the PO file content and parse it into messages
|
||||
var content = PoParser.readFile(file);
|
||||
var start = new Date();
|
||||
var lines = content.split(PoParser.REGEX_LINES);
|
||||
var idx = -1;
|
||||
var line = null;
|
||||
var m, value, nr;
|
||||
var msg;
|
||||
|
||||
var hasMoreLines = function() {
|
||||
return idx < lines.length - 1;
|
||||
};
|
||||
|
||||
var nextLine = function() {
|
||||
return (line = lines[idx += 1]) != null;
|
||||
};
|
||||
|
||||
var getContinuation = function(str) {
|
||||
var nLine;
|
||||
while ((nLine = lines[idx + 1]) != null) {
|
||||
if ((m = nLine.match(PoParser.REGEX_MSG_CONT)) != null) {
|
||||
str += m[1];
|
||||
nextLine();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
while (nextLine()) {
|
||||
if ((m = line.match(PoParser.REGEX_MSGID)) != null) {
|
||||
value = getContinuation(m[1]);
|
||||
if (value) {
|
||||
msg = this.messages[this.messages.length] = new Message(value);
|
||||
}
|
||||
} else if ((m = line.match(PoParser.REGEX_MSGID_PLURAL)) != null) {
|
||||
value = getContinuation(m[1]);
|
||||
if (value && msg != null) {
|
||||
msg.pluralKey = value;
|
||||
}
|
||||
} else if ((m = line.match(PoParser.REGEX_MSGSTR)) != null) {
|
||||
nr = m[1];
|
||||
value = getContinuation(m[2]);
|
||||
if (value && msg != null) {
|
||||
nr = parseInt(nr, 10);
|
||||
msg.translations[nr || 0] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the array containing the parsed messages into a message
|
||||
* catalog script file and saves it on disk.
|
||||
* @param {java.io.File} outputDir The directory where the message
|
||||
* file should be saved
|
||||
*/
|
||||
PoParser.prototype.writeToFile = function(output) {
|
||||
var buf = new java.lang.StringBuffer();
|
||||
// write header
|
||||
buf.append('/**\n');
|
||||
buf.append(' * Instantiate the messages namespace if it\'s not already existing\n');
|
||||
buf.append(' */\n');
|
||||
var objPath = "";
|
||||
if (this.namespace) {
|
||||
objPath += this.namespace;
|
||||
buf.append('if (!global.' + objPath + ') {\n');
|
||||
buf.append(' global.' + objPath + ' = {};\n');
|
||||
buf.append('}\n');
|
||||
objPath += ".";
|
||||
}
|
||||
objPath += "messages";
|
||||
buf.append('if (!global.' + objPath + ') {\n');
|
||||
buf.append(' global.' + objPath + ' = {};\n');
|
||||
buf.append('}\n\n');
|
||||
|
||||
buf.append('/**\n');
|
||||
buf.append(' * Messages for locale "' + this.localeKey + '"\n');
|
||||
buf.append(' */\n');
|
||||
objPath += "." + this.localeKey;
|
||||
buf.append('global.' + objPath + ' = {\n');
|
||||
// write messages
|
||||
for (var i=0;i<this.messages.length; i++) {
|
||||
this.messages[i].write(buf);
|
||||
}
|
||||
// write footer
|
||||
buf.append('};\n');
|
||||
|
||||
// write the message catalog into the outFile
|
||||
var file = new java.io.File(output, objPath + ".js");
|
||||
var writer = new java.io.FileWriter(file);
|
||||
writer.write(buf.toString());
|
||||
// writer.write(buf.toString().getBytes("UTF-8"));
|
||||
writer.close();
|
||||
print("generated messages file " + file.getAbsolutePath());
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new message object containing the singular- and
|
||||
* plural key plus their translations
|
||||
* @param {String} singularKey The singular key of the message
|
||||
* @returns A newly created Message instance
|
||||
* @constructor
|
||||
*/
|
||||
var Message = function(singularKey) {
|
||||
this.singularKey = singularKey;
|
||||
this.pluralKey = null;
|
||||
this.translations = [];
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps this message as JavaScript literal key-value pair(s)
|
||||
* @param {java.lang.StringBuffer} buf The buffer to append the dumped
|
||||
* string to
|
||||
*/
|
||||
Message.prototype.write = function(buf) {
|
||||
var writeLine = function(key, value) {
|
||||
buf.append(' "');
|
||||
buf.append(key);
|
||||
buf.append('": "');
|
||||
if (value !== null && value !== undefined) {
|
||||
buf.append(value);
|
||||
}
|
||||
buf.append('",\n');
|
||||
};
|
||||
|
||||
if (this.singularKey != null) {
|
||||
writeLine(this.singularKey, this.translations[0]);
|
||||
if (this.pluralKey != null) {
|
||||
writeLine(this.pluralKey, this.translations[1]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main script body
|
||||
*/
|
||||
if (arguments.length < 2) {
|
||||
print("Usage:");
|
||||
print("PoParser.js <input> <output> [namespace]");
|
||||
print("<input>: Either a single .po file or a directory containing .po files");
|
||||
print("<output>: The directory where the generated messages files should be stored");
|
||||
print("[namespace]: An optional global namespace where the messages should be");
|
||||
print(" stored (eg. a namespace like 'jala' will lead to messages");
|
||||
print(" stored in global.jala.messages by their locale.");
|
||||
quit();
|
||||
}
|
||||
|
||||
var input = new java.io.File(arguments[0]);
|
||||
var output = new java.io.File(arguments[1]);
|
||||
var namespace = arguments[2];
|
||||
|
||||
// check if the output destination is a directory
|
||||
if (output.isFile()) {
|
||||
print("Invalid arguments: the output destination must be a directory.");
|
||||
quit();
|
||||
}
|
||||
|
||||
if (namespace && namespace.indexOf(".") != -1) {
|
||||
print("Invalid arguments: Please don't specify complex object paths, as this");
|
||||
print("would corrupt the messages file.");
|
||||
quit();
|
||||
}
|
||||
|
||||
// parse the PO file(s) and create the message catalog files
|
||||
var parser;
|
||||
if (input.isDirectory()) {
|
||||
var files = input.listFiles();
|
||||
var file;
|
||||
for (var i=0;i<files.length;i++) {
|
||||
file = files[i];
|
||||
if (file.getName().endsWith(".po")) {
|
||||
parser = new PoParser(namespace);
|
||||
parser.parse(file);
|
||||
parser.writeToFile(output);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parser = new PoParser(namespace);
|
||||
parser.parse(input);
|
||||
parser.writeToFile(output);
|
||||
}
|
92
modules/jala/util/HopKit/scripts/jsant.js
Normal file
92
modules/jala/util/HopKit/scripts/jsant.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the ``License'');
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an ``AS IS'' BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Helper methods for use as embedded JavaScript in Ant.
|
||||
*/
|
||||
|
||||
|
||||
Util = {
|
||||
counter:0
|
||||
};
|
||||
|
||||
Util.readFile = function (filename) {
|
||||
Util.counter++;
|
||||
var loader = project.createTask("loadfile");
|
||||
loader.setSrcFile(new java.io.File(filename));
|
||||
loader.setProperty("loaderResult" + Util.counter);
|
||||
try {
|
||||
loader.execute();
|
||||
return String(project.getProperty("loaderResult" + Util.counter));
|
||||
} catch (anyerror) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
Util.loadProperties = function(filename) {
|
||||
var props = new java.util.Properties();
|
||||
var inStream = new java.io.FileInputStream(filename);
|
||||
props.load(inStream);
|
||||
return props;
|
||||
};
|
||||
|
||||
Util.log = function (str) {
|
||||
java.lang.System.out.println(str);
|
||||
};
|
||||
|
||||
Util.getFile = function(dir, file) {
|
||||
return new java.io.File(new java.io.File(dir).getCanonicalPath(), file);
|
||||
};
|
||||
|
||||
Util.writeToFile = function(filename, str) {
|
||||
var echo = project.createTask("echo");
|
||||
echo.setMessage(str);
|
||||
echo.setFile(new java.io.File(filename));
|
||||
echo.execute();
|
||||
return true;
|
||||
};
|
||||
|
||||
Util.setProperty = function(propName, propValue) {
|
||||
var prop = project.createTask("property");
|
||||
prop.setName(propName);
|
||||
prop.setValue(propValue);
|
||||
prop.execute();
|
||||
};
|
||||
|
||||
String.prototype.trim = function() {
|
||||
return this.match(/^\s*(.*?)\s*$/)[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* transforms the first n characters of a string to uppercase
|
||||
* @param Number amount of characters to transform
|
||||
* @return String the resulting string
|
||||
*/
|
||||
String.prototype.capitalize = function(limit) {
|
||||
if (limit == null)
|
||||
limit = 1;
|
||||
var head = this.substring(0, limit);
|
||||
var tail = this.substring(limit, this.length);
|
||||
return head.toUpperCase() + tail.toLowerCase();
|
||||
};
|
2531
modules/jala/util/HopKit/scripts/jslint.js
Normal file
2531
modules/jala/util/HopKit/scripts/jslint.js
Normal file
File diff suppressed because it is too large
Load diff
316
modules/jala/util/HopKit/scripts/jsmin.js
Normal file
316
modules/jala/util/HopKit/scripts/jsmin.js
Normal file
|
@ -0,0 +1,316 @@
|
|||
/* jsmin.js - 2006-08-31
|
||||
Author: Franck Marcia
|
||||
This work is an adaptation of jsminc.c published by Douglas Crockford.
|
||||
Permission is hereby granted to use the Javascript version under the same
|
||||
conditions as the jsmin.c on which it is based.
|
||||
|
||||
jsmin.c
|
||||
2006-05-04
|
||||
|
||||
Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The Software shall be used for Good, not Evil.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Update:
|
||||
add level:
|
||||
1: minimal, keep linefeeds if single
|
||||
2: normal, the standard algorithm
|
||||
3: agressive, remove any linefeed and doesn't take care of potential
|
||||
missing semicolons (can be regressive)
|
||||
store stats
|
||||
jsmin.oldSize
|
||||
jsmin.newSize
|
||||
*/
|
||||
|
||||
String.prototype.has = function(c) {
|
||||
return this.indexOf(c) > -1;
|
||||
};
|
||||
|
||||
function jsmin(comment, input, level) {
|
||||
|
||||
if (input === undefined) {
|
||||
input = comment;
|
||||
comment = '';
|
||||
level = 2;
|
||||
} else if (level === undefined || level < 1 || level > 3) {
|
||||
level = 2;
|
||||
}
|
||||
|
||||
if (comment.length > 0) {
|
||||
comment += '\n';
|
||||
}
|
||||
|
||||
var a = '',
|
||||
b = '',
|
||||
EOF = -1,
|
||||
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
|
||||
DIGITS = '0123456789',
|
||||
ALNUM = LETTERS + DIGITS + '_$\\',
|
||||
theLookahead = EOF;
|
||||
|
||||
|
||||
/* isAlphanum -- return true if the character is a letter, digit, underscore,
|
||||
dollar sign, or non-ASCII character.
|
||||
*/
|
||||
|
||||
function isAlphanum(c) {
|
||||
return c != EOF && (ALNUM.has(c) || c.charCodeAt(0) > 126);
|
||||
}
|
||||
|
||||
|
||||
/* get -- return the next character. Watch out for lookahead. If the
|
||||
character is a control character, translate it to a space or
|
||||
linefeed.
|
||||
*/
|
||||
|
||||
function get() {
|
||||
|
||||
var c = theLookahead;
|
||||
if (get.i == get.l) {
|
||||
return EOF;
|
||||
}
|
||||
theLookahead = EOF;
|
||||
if (c == EOF) {
|
||||
c = input.charAt(get.i);
|
||||
++get.i;
|
||||
}
|
||||
if (c >= ' ' || c == '\n') {
|
||||
return c;
|
||||
}
|
||||
if (c == '\r') {
|
||||
return '\n';
|
||||
}
|
||||
return ' ';
|
||||
}
|
||||
|
||||
get.i = 0;
|
||||
get.l = input.length;
|
||||
|
||||
|
||||
/* peek -- get the next character without getting it.
|
||||
*/
|
||||
|
||||
function peek() {
|
||||
theLookahead = get();
|
||||
return theLookahead;
|
||||
}
|
||||
|
||||
|
||||
/* next -- get the next character, excluding comments. peek() is used to see
|
||||
if a '/' is followed by a '/' or '*'.
|
||||
*/
|
||||
|
||||
function next() {
|
||||
|
||||
var c = get();
|
||||
if (c == '/') {
|
||||
switch (peek()) {
|
||||
case '/':
|
||||
for (;;) {
|
||||
c = get();
|
||||
if (c <= '\n') {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
get();
|
||||
for (;;) {
|
||||
switch (get()) {
|
||||
case '*':
|
||||
if (peek() == '/') {
|
||||
get();
|
||||
return ' ';
|
||||
}
|
||||
break;
|
||||
case EOF:
|
||||
throw 'Error: Unterminated comment.';
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* action -- do something! What you do is determined by the argument:
|
||||
1 Output A. Copy B to A. Get the next B.
|
||||
2 Copy B to A. Get the next B. (Delete A).
|
||||
3 Get the next B. (Delete B).
|
||||
action treats a string as a single character. Wow!
|
||||
action recognizes a regular expression if it is preceded by ( or , or =.
|
||||
*/
|
||||
|
||||
function action(d) {
|
||||
|
||||
var r = [];
|
||||
|
||||
if (d == 1) {
|
||||
r.push(a);
|
||||
}
|
||||
|
||||
if (d < 3) {
|
||||
a = b;
|
||||
if (a == '\'' || a == '"') {
|
||||
for (;;) {
|
||||
r.push(a);
|
||||
a = get();
|
||||
if (a == b) {
|
||||
break;
|
||||
}
|
||||
if (a <= '\n') {
|
||||
throw 'Error: unterminated string literal: ' + a;
|
||||
}
|
||||
if (a == '\\') {
|
||||
r.push(a);
|
||||
a = get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b = next();
|
||||
|
||||
if (b == '/' && '(,=:[!&|'.has(a)) {
|
||||
r.push(a);
|
||||
r.push(b);
|
||||
for (;;) {
|
||||
a = get();
|
||||
if (a == '/') {
|
||||
break;
|
||||
} else if (a =='\\') {
|
||||
r.push(a);
|
||||
a = get();
|
||||
} else if (a <= '\n') {
|
||||
throw 'Error: unterminated Regular Expression literal';
|
||||
}
|
||||
r.push(a);
|
||||
}
|
||||
b = next();
|
||||
}
|
||||
|
||||
return r.join('');
|
||||
}
|
||||
|
||||
|
||||
/* m -- Copy the input to the output, deleting the characters which are
|
||||
insignificant to JavaScript. Comments will be removed. Tabs will be
|
||||
replaced with spaces. Carriage returns will be replaced with
|
||||
linefeeds.
|
||||
Most spaces and linefeeds will be removed.
|
||||
*/
|
||||
|
||||
function m() {
|
||||
|
||||
var r = [];
|
||||
a = '\n';
|
||||
|
||||
r.push(action(3));
|
||||
|
||||
while (a != EOF) {
|
||||
switch (a) {
|
||||
case ' ':
|
||||
if (isAlphanum(b)) {
|
||||
r.push(action(1));
|
||||
} else {
|
||||
r.push(action(2));
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
switch (b) {
|
||||
case '{':
|
||||
case '[':
|
||||
case '(':
|
||||
case '+':
|
||||
case '-':
|
||||
r.push(action(1));
|
||||
break;
|
||||
case ' ':
|
||||
r.push(action(3));
|
||||
break;
|
||||
default:
|
||||
if (isAlphanum(b)) {
|
||||
r.push(action(1));
|
||||
} else {
|
||||
if (level == 1 && b != '\n') {
|
||||
r.push(action(1));
|
||||
} else {
|
||||
r.push(action(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (b) {
|
||||
case ' ':
|
||||
if (isAlphanum(a)) {
|
||||
r.push(action(1));
|
||||
break;
|
||||
}
|
||||
r.push(action(3));
|
||||
break;
|
||||
case '\n':
|
||||
if (level == 1 && a != '\n') {
|
||||
r.push(action(1));
|
||||
} else {
|
||||
switch (a) {
|
||||
case '}':
|
||||
case ']':
|
||||
case ')':
|
||||
case '+':
|
||||
case '-':
|
||||
case '"':
|
||||
case '\'':
|
||||
if (level == 3) {
|
||||
r.push(action(3));
|
||||
} else {
|
||||
r.push(action(1));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isAlphanum(a)) {
|
||||
r.push(action(1));
|
||||
} else {
|
||||
r.push(action(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
r.push(action(1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r.join('');
|
||||
}
|
||||
|
||||
jsmin.oldSize = input.length;
|
||||
ret = m(input);
|
||||
jsmin.newSize = ret.length;
|
||||
|
||||
return comment + ret;
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue