Index: /CKLangTool/trunk/_source/includes/ckjpformat.js
===================================================================
--- /CKLangTool/trunk/_source/includes/ckjpformat.js	(revision 7082)
+++ /CKLangTool/trunk/_source/includes/ckjpformat.js	(revision 7083)
@@ -8,5 +8,5 @@
 ( function()
 {
-	CKLANGTOOL.jpformat = function()
+	CKLANGTOOL.jprops = function()
 	{
 	};
@@ -46,5 +46,5 @@
 	 */
 
-	CKLANGTOOL.jpformat.prototype =
+	CKLANGTOOL.jprops.prototype =
 	{
 		run : function()
Index: /CKLangTool/trunk/_source/includes/cklangtool.js
===================================================================
--- /CKLangTool/trunk/_source/includes/cklangtool.js	(revision 7082)
+++ /CKLangTool/trunk/_source/includes/cklangtool.js	(revision 7083)
@@ -36,63 +36,114 @@
 };
 
-/**
- * Load language file and return an object with the whole translation.
- */
-CKLANGTOOL.loadLanguageFile = function( file )
-{
-	var translationCode = 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file );
-
-	var cx = Context.enter(), scope = cx.initStandardObjects();
-
-	try
-	{
-		cx.evaluateString( scope, translationCode, file.getName(), 1, null );
-
-		var languageCode = '';
-
-		/*
-		 * Get the number of variables in parent scope.
-		 */
-		var size = 0;
-		for ( var i in scope )
-		{
-			size++;
-		}
-
-		/*
-		 * If there is more than one variable, then it's not a CKEDITOR language file.
-		 */
-		if ( size > 1 )
-		{
-			/**
-			 * Return the first variable from parent scope different than
-			 * CKEDITOR.
-			 */
-			for ( var i in scope )
-			{
-				if ( i != "CKEDITOR" )
-					return { 'languageCode' : languageCode, 'translation' : scope[i] };
-			}
-		}
-		else
-		{
-			/*
-			 * Return the first entry from scope.CKEDITOR.lang object
-			 */
-			for ( var i in scope.CKEDITOR.lang )
-			{
-				languageCode = i;
-				return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i] };
-			}
-		}
-	}
-	catch ( e )
-	{
-		throw ( "Language file is invalid: " + file.getAbsolutePath() + ".\nError: " + e.message);
-	}
-};
-
 ( function()
 {
+	/**
+	 * Load language file and return an object with the whole translation.
+	 */
+	CKLANGTOOL.loadLanguageFile = function( file )
+	{
+		var format = this.theFileFormat( file );
+		switch( format )
+		{
+			case CKLANGTOOL.FORMAT_JSON:
+				var translationCode = 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file );
+
+				var cx = Context.enter(), scope = cx.initStandardObjects();
+
+				try
+				{
+					cx.evaluateString( scope, translationCode, file.getName(), 1, null );
+
+					var languageCode = '';
+
+					/*
+					 * Get the number of variables in parent scope.
+					 */
+					var size = 0;
+					for ( var i in scope )
+					{
+						size++;
+					}
+
+					/*
+					 * If there is more than one variable, then it's not a CKEDITOR language file.
+					 */
+					if ( size > 1 )
+					{
+						/**
+						 * Return the first variable from parent scope different than
+						 * CKEDITOR.
+						 */
+						for ( var i in scope )
+						{
+							if ( i != "CKEDITOR" )
+								return { 'languageCode' : languageCode, 'translation' : scope[i] };
+						}
+					}
+					else
+					{
+						/*
+						 * Return the first entry from scope.CKEDITOR.lang object
+						 */
+						for ( var i in scope.CKEDITOR.lang )
+						{
+							languageCode = i;
+							return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i] };
+						}
+					}
+				}
+				catch ( e )
+				{
+					throw ( "Language file is invalid: " + file.getAbsolutePath() + ".\nError: " + e.message);
+				}
+
+			case CKLANGTOOL.FORMAT_GT:
+
+				function msgstr( val )
+				{
+					// [ 'msgid-plural', 'trans', 'trans-plural' ... ]
+					var str = val[ 1 ];
+
+					// Restore line breaks.
+					return str ? str.replace( /\\n/g, '\r\n' ) : '';
+				}
+
+				var pom = parsePO( CKLANGTOOL.io.readFile( file ) ),
+					headers = pom[ '' ],
+					languageCode = headers.language;
+
+				var trans = {}, translated, keys, key, entry;
+				for ( var msgid in pom )
+				{
+					translated = msgstr( pom[ msgid ]);
+					// Bypass file header and untranslated ones.
+					if ( msgid && translated )
+					{
+						keys = msgid.split( '.' );
+						entry = trans;
+
+						for ( var i = 0, level = keys.length; i < level; i++ )
+						{
+							key = keys[ i ];
+							if ( !entry[ key ] )
+							{
+								if ( i < level - 1 )
+									entry = entry[ key ] = {};
+								else
+									entry[ key ] = translated;
+							}
+							else if ( typeof entry[ key ] == 'object' )
+								entry = entry[ key ];
+						}
+					}
+				}
+
+				return { 'languageCode' : languageCode, 'translation' : trans };
+
+			default:
+				throw 'Load translation of the <' + format + '> format is not supported';
+		}
+	};
+
 	CKLANGTOOL.translator = function()
 	{
@@ -113,18 +164,51 @@
 	function checkFile( file )
 	{
-		var compilerEnv = new CompilerEnvirons();
-		var errorReporter = compilerEnv.getErrorReporter();
-		var parser = new Parser( compilerEnv, errorReporter );
-
-		try
-		{
-			parser.parse( 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file ), null, 1 );
-			return false;
-		}
-		catch ( e )
-		{
-			throw ("Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message);
-		}
+		var format = CKLANGTOOL.theFileFormat( file );
+		if ( format == CKLANGTOOL.FORMAT_JSON )
+		{
+			var compilerEnv = new CompilerEnvirons();
+			var errorReporter = compilerEnv.getErrorReporter();
+			var parser = new Parser( compilerEnv, errorReporter );
+
+			try
+			{
+				parser.parse( 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file ), null, 1 );
+				return false;
+			}
+			catch ( e )
+			{
+				throw ("Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message);
+			}
+		}
+		else
+			return;
 	}
+
+	( function()
+	{
+		CKLANGTOOL.FORMAT_JSON = 'json';
+		CKLANGTOOL.FORMAT_JP = 'jprops';
+		CKLANGTOOL.FORMAT_GT = 'gettext';
+
+		function extToFormat( ext )
+		{
+			var format =
+			{
+				'js': CKLANGTOOL.FORMAT_JSON,
+				'po' : CKLANGTOOL.FORMAT_GT,
+				'properties': CKLANGTOOL.FORMAT_JP
+			}[ ext ];
+
+			return format || 'unknown';
+		}
+
+		CKLANGTOOL.theFileFormat = function( file )
+		{
+			var ext = CKLANGTOOL.io.getExtension( file.getName() )
+			return extToFormat( ext );
+		};
+
+	} )();
+
 
 	var regexLib =
@@ -221,5 +305,5 @@
 				}
 
-				/* 
+				/*
 				 * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key.
 				 */
@@ -496,9 +580,12 @@
 		var result = CKLANGTOOL.loadLanguageFile( file );
 		var translation = result.translation;
-		var fileInformation = CKLANGTOOL.analyzeLanguageFile( file ),
-			missingKeys = fileInformation.missingKeys;
-
-		fileOverviewBlock = fileInformation.fileOverviewBlock;
 		languageCode = result.languageCode;
+
+		var dst = new File( CKLANGTOOL.languageDir, languageCode + '.js' );
+		var info = CKLANGTOOL.analyzeLanguageFile( dst );
+		// No mark missing support in other formats.
+		var missingKeys =  CKLANGTOOL.format == CKLANGTOOL.FORMAT_JSON ? info.missingKeys : {};
+		fileOverviewBlock = info.fileOverviewBlock;
+
 
 		while ( matcher.find() )
@@ -558,8 +645,9 @@
 		}
 
-		CKLANGTOOL.io.saveFile( file, lines.join( "\r\n" ), false );
+		CKLANGTOOL.io.saveFile( dst, lines.join( "\r\n" ), false );
 
 		var result =
 		{
+			langFile : dst.getName(),
 			found :found,
 			missing :missing
@@ -576,19 +664,16 @@
 	CKLANGTOOL.translator.prototype =
 	{
-		run : function()
+		run : function( transDir )
 		{
 			CKLANGTOOL.template = CKLANGTOOL.translator.createTemplate( CKLANGTOOL.templateFile );
-			var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile ); 
+			var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile );
 			CKLANGTOOL.englishTranslation = result.translation; 
 
-			var children = CKLANGTOOL.languageDir.list();
-			var errors, file, status = {}, languages = [];
+			var children = transDir.list();
+			var file, languages = [], status = {};
 			var foundFiles = false;
 
 			for ( var i = 0 ; i < children.length ; i++ )
 			{
-				if ( children[ i ] == 'en.js' )
-					continue;
-
 				/**
 				 * Skip files beginning with underscore character.
@@ -596,19 +681,22 @@
 				if ( children[ i ].charAt(0) == 95 )
 					continue;
-				
-				if ( CKLANGTOOL.io.getExtension( children[ i ] ) != "js" )
-					continue;
-
-				file = new File( CKLANGTOOL.languageDir, children[ i ] );
-				if ( file.isFile() )
-				{
-					print( "Processing " + file.getAbsolutePath() );
-					result = processFile( file );
-					checkFile( file );
-
-					languages.push( children[ i ] );
-					status[ children[ i ] ] = padRight( children[ i ], 12 ) + "Found: " + result.found + " Missing: " + result.missing;
-					foundFiles = true;
-				}
+
+				// Bypass source language file.
+				if ( children[ i ].match( /^en\./ ) )
+					continue;
+
+				file = new File( transDir, children[ i ] );
+
+				// Bypass directory and irrelevant files.
+				if ( ! ( file.isFile() && CKLANGTOOL.theFileFormat( file ) == CKLANGTOOL.format ) )
+					continue;
+
+				print( "Processing " + file.getAbsolutePath() );
+				result = processFile( file );
+				checkFile( file );
+
+				languages.push( result.langFile );
+				status[ result.langFile ] = padRight( result.langFile, 12 ) + "Found: " + result.found + " Missing: " + result.missing;
+				foundFiles = true;
 			}
 
Index: /CKLangTool/trunk/_source/includes/ckpoformat.js
===================================================================
--- /CKLangTool/trunk/_source/includes/ckpoformat.js	(revision 7082)
+++ /CKLangTool/trunk/_source/includes/ckpoformat.js	(revision 7083)
@@ -5,4 +5,5 @@
 
 importPackage( java.util.regex );
+importClass( java.text.SimpleDateFormat );
 
 ( function()
@@ -13,5 +14,5 @@
 	var missingKeys;
 
-	CKLANGTOOL.poformat = function()
+	CKLANGTOOL.gettext = function()
 	{
 		return {
@@ -60,8 +61,8 @@
 	function loadMetaInformation()
 	{
-		if (!CKLANGTOOL.metafilePath)
+		if (!CKLANGTOOL.metaFile)
 			return {};
 
-		var lines = CKLANGTOOL.io.readFileIntoArray(CKLANGTOOL.metafilePath);
+		var lines = CKLANGTOOL.io.readFileIntoArray(CKLANGTOOL.metaFile);
 		var meta = {};
 
@@ -130,24 +131,27 @@
 	}
 
-	function poHeader()
-	{
-		return [
-		'"Project-Id-Version: CKEditor\\n"',
-		'"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\\n"',
-		'"POT-Creation-Date: 2011-05-31 00:00+0000\\n"',
-		'"PO-Revision-Date: 2011-05-31 00:30+0000\\n"',
-		'"Last-Translator: CKEditor\\n"',
-		'"Language-Team: CKEditor translation team\\n"',
-		'"MIME-Version: 1.0\\n"',
-		'"Content-Type: text/plain; charset=UTF-8\\n"',
-		'"Content-Transfer-Encoding: 8bit\\n"',
-		'"Language: en\\n"',
-		'"Plural-Forms: nplurals=2; plural=(n != 1)\\n"',
-		'\n'
-		].join( '\n' );
-	}
-	
 	function processFile( file )
 	{
+		function poHeader()
+		{
+			var now = new SimpleDateFormat("yyyy-MM-dd HH:mmZ").format( new java.util.Date());
+			var headers = [
+			'"Project-Id-Version: CKEditor\\n"',
+			'"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\\n"',
+			'"POT-Creation-Date: 2011-05-31 00:00+0000\\n"',
+			'"PO-Revision-Date: ' + now + '\\n"',
+			'"Last-Translator: CKEditor\\n"',
+			'"Language-Team: CKEditor translation team\\n"',
+			'"MIME-Version: 1.0\\n"',
+			'"Content-Type: text/plain; charset=UTF-8\\n"',
+			'"Content-Transfer-Encoding: 8bit\\n"',
+			'"Language: ' + language.languageCode + '\\n"',
+			'"Plural-Forms: nplurals=2; plural=(n != 1)\\n"',
+			'\n'
+			].join( '\n' );
+
+			return new java.lang.String( poEntry( '', '', license, overview ) ).trim() + '\n' + headers;
+		}
+
 		// License Info
 		var fileInfo = CKLANGTOOL.analyzeLanguageFile( file );
@@ -158,6 +162,6 @@
 		missingKeys = fileInfo.missingKeys;
 
-		var language = CKLANGTOOL.loadLanguageFile( file );
-		return poEntry( '', '', license, overview ) + poHeader() + printObject( '', language.translation );
+		var language = CKLANGTOOL.loadLanguageFile( file, 'json' );
+		return poHeader() + printObject( '', language.translation );
 	}
 
Index: /CKLangTool/trunk/_source/includes/po_parser.js
===================================================================
--- /CKLangTool/trunk/_source/includes/po_parser.js	(revision 7083)
+++ /CKLangTool/trunk/_source/includes/po_parser.js	(revision 7083)
@@ -0,0 +1,217 @@
+/*
+Pure Javascript implementation of the GNU Gettext.
+Copyright (C) 2008 Joshua I. Miller <unrtst@cpan.org>, all rights reserved
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU Library General Public License as published
+by the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program 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
+Library General Public License for more details.
+*/
+
+( function()
+{
+	function parse_po_dequote( str )
+	{
+		var match;
+		if ( match = str.match( /^"(.*)"/ ) )
+		{
+			str = match[1];
+		}
+		// unescale all embedded quotes (fixes bug #17504)
+		str = str.replace( /\\"/g, "\"" );
+		return str;
+	}
+
+	var GLUE = '\004';
+
+	function parse_po(data)
+	{
+		var rv = {};
+		var buffer = {};
+		var lastbuffer = "";
+		var errors = [];
+		var lines = data.split( "\n" );
+		for ( var i = 0; i < lines.length; i++ )
+		{
+			// chomp
+			lines[i] = lines[i].replace( /(\n|\r)+$/, '' );
+
+			var match;
+
+			// Empty line / End of an entry.
+			if ( /^$/.test( lines[i] ) )
+			{
+				if ( typeof(buffer['msgid']) != 'undefined' )
+				{
+					var msg_ctxt_id = (typeof(buffer['msgctxt']) != 'undefined' &&
+							buffer['msgctxt'].length) ?
+									  buffer['msgctxt'] + GLUE + buffer['msgid'] :
+									  buffer['msgid'];
+					var msgid_plural = (typeof(buffer['msgid_plural']) != 'undefined' &&
+							buffer['msgid_plural'].length) ?
+									   buffer['msgid_plural'] :
+									   null;
+
+					// find msgstr_* translations and push them on
+					var trans = [];
+					for ( var str in buffer )
+					{
+						var match;
+						if ( match = str.match( /^msgstr_(\d+)/ ) )
+							trans[parseInt( match[1] )] = buffer[str];
+					}
+					trans.unshift( msgid_plural );
+
+					// only add it if we've got a translation
+					// NOTE: this doesn't conform to msgfmt specs
+					if ( trans.length > 1 ) rv[msg_ctxt_id] = trans;
+
+					buffer = {};
+					lastbuffer = "";
+				}
+
+				// comments
+			} else if ( /^#/.test( lines[i] ) )
+			{
+				continue;
+
+				// msgctxt
+			} else if ( match = lines[i].match( /^msgctxt\s+(.*)/ ) )
+			{
+				lastbuffer = 'msgctxt';
+				buffer[lastbuffer] = parse_po_dequote( match[1] );
+
+				// msgid
+			} else if ( match = lines[i].match( /^msgid\s+(.*)/ ) )
+			{
+				lastbuffer = 'msgid';
+				buffer[lastbuffer] = parse_po_dequote( match[1] );
+
+				// msgid_plural
+			} else if ( match = lines[i].match( /^msgid_plural\s+(.*)/ ) )
+			{
+				lastbuffer = 'msgid_plural';
+				buffer[lastbuffer] = parse_po_dequote( match[1] );
+
+				// msgstr
+			} else if ( match = lines[i].match( /^msgstr\s+(.*)/ ) )
+			{
+				lastbuffer = 'msgstr_0';
+				buffer[lastbuffer] = parse_po_dequote( match[1] );
+
+				// msgstr[0] (treak like msgstr)
+			} else if ( match = lines[i].match( /^msgstr\[0\]\s+(.*)/ ) )
+			{
+				lastbuffer = 'msgstr_0';
+				buffer[lastbuffer] = parse_po_dequote( match[1] );
+
+				// msgstr[n]
+			} else if ( match = lines[i].match( /^msgstr\[(\d+)\]\s+(.*)/ ) )
+			{
+				lastbuffer = 'msgstr_' + match[1];
+				buffer[lastbuffer] = parse_po_dequote( match[2] );
+
+				// continued string
+			} else if ( /^"/.test( lines[i] ) )
+			{
+				buffer[lastbuffer] += parse_po_dequote( lines[i] );
+				// something strange
+			}
+			else
+			{
+				errors.push( "Strange line [" + i + "] : " + lines[i] );
+			}
+		}
+
+
+		// handle the final entry
+		if ( typeof(buffer['msgid']) != 'undefined' )
+		{
+			var msg_ctxt_id = (typeof(buffer['msgctxt']) != 'undefined' &&
+					buffer['msgctxt'].length) ?
+							  buffer['msgctxt'] + GLUE + buffer['msgid'] :
+							  buffer['msgid'];
+			var msgid_plural = (typeof(buffer['msgid_plural']) != 'undefined' &&
+					buffer['msgid_plural'].length) ?
+							   buffer['msgid_plural'] :
+							   null;
+
+			// find msgstr_* translations and push them on
+			var trans = [];
+			for ( var str in buffer )
+			{
+				var match;
+				if ( match = str.match( /^msgstr_(\d+)/ ) )
+					trans[parseInt( match[1] )] = buffer[str];
+			}
+			trans.unshift( msgid_plural );
+
+			// only add it if we've got a translation
+			// NOTE: this doesn't conform to msgfmt specs
+			if ( trans.length > 1 ) rv[msg_ctxt_id] = trans;
+
+			buffer = {};
+			lastbuffer = "";
+		}
+
+
+		// parse out the header
+		if ( rv[""] && rv[""][1] )
+		{
+			var cur = {};
+			var hlines = rv[""][1].split( /\\n/ );
+			for ( var i = 0; i < hlines.length; i++ )
+			{
+				if ( ! hlines.length ) continue;
+
+				var pos = hlines[i].indexOf( ':', 0 );
+				if ( pos != -1 )
+				{
+					var key = hlines[i].substring( 0, pos );
+					var val = hlines[i].substring( pos + 1 );
+					var keylow = key.toLowerCase();
+
+					if ( cur[keylow] && cur[keylow].length )
+					{
+						errors.push( "SKIPPING DUPLICATE HEADER LINE: " + hlines[i] );
+					} else if ( /#-#-#-#-#/.test( keylow ) )
+					{
+						errors.push( "SKIPPING ERROR MARKER IN HEADER: " + hlines[i] );
+					}
+					else
+					{
+						// remove begining spaces if any
+						val = val.replace( /^\s+/, '' );
+						cur[keylow] = val;
+					}
+
+				}
+				else
+				{
+					errors.push( "PROBLEM LINE IN HEADER: " + hlines[i] );
+					cur[hlines[i]] = '';
+				}
+			}
+
+			// replace header string with assoc array
+			rv[""] = cur;
+		}
+		else
+		{
+			rv[""] = {};
+		}
+
+		// TODO: XXX: if there are errors parsing, what do we want to do?
+		// GNU Gettext silently ignores errors. So will we.
+		// alert( "Errors parsing po file:\n" + errors.join("\n") );
+
+		return rv;
+	}
+
+	this.parsePO = parse_po;
+} )();
Index: /CKLangTool/trunk/_source/langtool.js
===================================================================
--- /CKLangTool/trunk/_source/langtool.js	(revision 7082)
+++ /CKLangTool/trunk/_source/langtool.js	(revision 7083)
@@ -7,4 +7,5 @@
 importClass( java.lang.System );
 importClass( java.io.File );
+importClass( java.util.Scanner );
 
 /*
@@ -55,35 +56,22 @@
 CKLANGTOOL.load( 'cklangtool.includes.ckjpformat' );
 CKLANGTOOL.load( 'cklangtool.includes.ckpoformat' );
+CKLANGTOOL.load( 'cklangtool.includes.po_parser' );
 CKLANGTOOL.load( 'cklangtool.includes.io' );
 
 if ( !arguments[0] || arguments[0] == '-help' || arguments[0] == '/?' )
-	error( 'Usage: ' + command + ' lang_dir [-jpformat=dest_dir]|[-poformat=dest_dir] [-metafile=path]'
-			+ '\n\n CKLangTool corrects translation files and creates report about missing translations.'
-			+ '\n\n -jpformat  Convert files to java properties format and save them in dest_dir'
-			+ '\n\n -poformat  Convert files to GNU gettext PO format and save them in dest_dir.'
-			+ '\n\n -metafile  Path to meta file (used only in conjuction with -poformat).'
+	error( 'Usage: ' + command + ' command lang_dir dest_dir'
+			+ '\n\nCKLangTool corrects translation files and creates report about missing translations.'
+
+			+ '\n\nCommands:'
+			+ '\nupdate  Update editor\'s language files (editor\'s "lang" folder) with new text entries from translation files with specified format.'
+			+ '\noutput  Export editor\'s language files (editor\'s "lang" folder) to translation files with specified format.'
+
+			+ '\n\nOptions:'
+			+ '\n[-f|--format]=json|gettext|jprops  Format of language file when update from or export translation entries to, default to json.'
+			+ '\n\t json - A private JavaScript format used as runtime language files in CKEditor.'
+			+ '\n\t getext - The versatile GNU Gettext format, simplified to fit for CKEditor.'
+			+ '\n\t jprops - The Java Properties file format.'
+		   + '\n[-m|--metafile]=path  Specify the path to an optional meta file which used only by the Gettext format for context information.'
 			+ '\n' );
-
-for ( var i = 0 ; i < arguments.length ; i++ )
-{
-	var arg = arguments[i], match;
-	if ( match = arg.match( /^-(\w+format)=(.*?)$/ ) )
-	{
-		var destDir = match[ 2 ];
-		CKLANGTOOL.destinationDir = new File( destDir );
-		if ( CKLANGTOOL.destinationDir.exists() )
-			error( 'Destination directory already exists: ' + CKLANGTOOL.destinationDir.getAbsolutePath() );
-		else
-			CKLANGTOOL.destinationDir.mkdir();
-		CKLANGTOOL.format = match[ 1 ];
-	}
-	if ( match = arg.match( /^-metafile=(.*?)$/ ) )
-	{
-		var metafilePath = match[ 1 ];
-		CKLANGTOOL.metafilePath = new File( metafilePath );
-		if ( !CKLANGTOOL.metafilePath.exists() )
-			error( 'Meta file does not exist: ' + CKLANGTOOL.metafilePath.getAbsolutePath() );
-	}
-}
 
 if ( arguments[0] == '-test' && !isCompiled )
@@ -91,12 +79,4 @@
 	CKLANGTOOL.load( 'test.test' );
 	quit();
-}
-
-CKLANGTOOL.languageDir = new File( arguments[0] );
-CKLANGTOOL.templateFile = new File( arguments[0], 'en.js' );
-
-if ( !CKLANGTOOL.templateFile.exists() )
-{
-	error( 'ERROR: The english language file "en.js" was not found (' + CKLANGTOOL.templateFile.getAbsolutePath() + ')' );
 }
 
@@ -107,24 +87,73 @@
 }
 
-( function()
+var arg, action, match, langDir, dstDir;
+for ( var i = 0 ; i < arguments.length ; i++ )
 {
-	try
+	var arg = arguments[ i ];
+	// Absorb sub command as first arg.
+	if ( !i )
+		action = arg;
+	else
 	{
-		if ( CKLANGTOOL.format == "json" )
+		// Parse options.
+		if ( match = arg.match( /^(?:-f|--format)=(.*?)$/ ) )
+			CKLANGTOOL.format = match[ 1 ];
+		else if ( match = arg.match( /^(-?:m|--metafile)=(.*?)$/ ) )
 		{
-			var translator = new CKLANGTOOL.translator();
-			translator.run();
+			CKLANGTOOL.metaFile = new File( match[ 1 ] );
+			if ( !CKLANGTOOL.metaFile.exists() )
+				error( 'Meta file does not exist: ' + CKLANGTOOL.metaFile.getAbsolutePath() );
+		}
+		else if ( !langDir )
+		{
+			langDir = new File( arg );
+			if ( !langDir.exists() )
+				error( 'Specified language directory not exist: ' + langDir.getAbsolutePath() );
 
+			CKLANGTOOL.languageDir = langDir;
+			CKLANGTOOL.templateFile = new File( langDir, 'en.js' );
+			if ( !CKLANGTOOL.templateFile.exists() )
+				error( 'ERROR: The english language file "en.js" was not found (' + CKLANGTOOL.templateFile.getAbsolutePath() + ')' );
 		}
-		// Convert or sync languages files from other format.
-		else
+		else if ( !dstDir )
 		{
-			var format = new CKLANGTOOL[ CKLANGTOOL.format ]();
-			format.run();
+			dstDir = new File( arg );
+
+			if ( !dstDir.isDirectory() )
+				dstDir.mkdir();
+			else if ( action == 'export' && dstDir.exists() )
+			{
+				var console = new Scanner( System[ 'in' ] );
+				print( 'Destination directory already exists, overwrite? [y/n]' );
+				var answer = console.next();
+				if ( answer == 'y' )
+					dstDir[ 'delete' ]();
+				else
+					quit();
+			}
+
+			CKLANGTOOL.destinationDir = dstDir;
 		}
 	}
-	catch ( e )
-	{
-		error( e );
-	}
-} )();
+}
+
+// Command arguments validation.
+if ( !( action in { 'update' : 1, 'export' : 1 } )
+		|| !CKLANGTOOL.languageDir
+		|| action == 'export' && !CKLANGTOOL.destinationDir )
+	error( 'Bad arguments: "' + arguments.join( ' ' ) +'", check help for usage.' );
+
+// Update from languages files.
+if ( action == 'update' )
+{
+	var translator = new CKLANGTOOL.translator();
+	translator.run( CKLANGTOOL.destinationDir || CKLANGTOOL.languageDir );
+}
+// Export translations to other formats.
+else if ( action == 'export' )
+{
+	var formatter = CKLANGTOOL[ CKLANGTOOL.format ];
+	if ( !formatter )
+		error( 'Output language files in ' + CKLANGTOOL.format + ' format is not supported.' );
+	new formatter().run();
+}
Index: /CKLangTool/trunk/test/_assets/gettext/de.js
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/de.js	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/de.js	(revision 7083)
@@ -0,0 +1,82 @@
+﻿/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * German language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Constains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang['de'] =
+{
+	/**
+	 * The language reading direction. Possible values are "rtl" for
+	 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
+	 * languages (like English).
+	 * @default 'ltr'
+	 */
+	dir : 'ltr',
+
+	/*
+	 * Screenreader titles. Please note that screenreaders are not always capable
+	 * of reading non-English words. So be careful while translating it.
+	 */
+	editorTitle		: 'Rich text editor, %1', // MISSING
+
+	// Toolbar buttons without dialogs.
+	source			: 'Quellcode',
+	newPage			: 'Neue Seite',
+	save			: 'Speichern',
+	preview			: 'Vorschau',
+
+	// Common messages and labels.
+	common :
+	{
+		browseServer	: 'Server durchsuchen',
+		url				: 'Bildauswahl',
+		protocol		: 'Protokoll',
+		confirmCancel	: 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING
+	},
+
+	// Link dialog.
+	link :
+	{
+		toolbar		: 'Link einfügen/editieren',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
+		noAnchors		: '(keine Anker im Dokument vorhanden)',
+		noUrl			: 'Bitte geben Sie die Link-URL an',
+		noEmail			: 'Bitte geben Sie e-Mail Adresse an'
+	},
+
+	// Table Dialog
+	table :
+	{
+		toolbar		: 'Tabelle',
+
+		cell :
+		{
+			menu			: 'Zelle',
+			insertBefore	: 'Zelle davor einfügen',
+		},
+
+		row :
+		{
+			menu			: 'Zeile',
+		},
+	},
+
+	// Button Dialog.
+	button :
+	{
+		typeRst		: 'Zurücksetzen'
+	},
+};
Index: /CKLangTool/trunk/test/_assets/gettext/de.po.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/de.po.correct.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/de.po.correct.txt	(revision 7083)
@@ -0,0 +1,76 @@
+# Copyright (c) 2003-__CURRENT_YEAR__, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+# Defines the object, for the German language.
+msgid ""
+msgstr ""
+"Project-Id-Version: CKEditor\n"
+"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\n"
+"POT-Creation-Date: 2011-05-31 00:00+0000\n"
+"PO-Revision-Date: 2011-05-31 00:30+0000\n"
+"Last-Translator: CKEditor\n"
+"Language-Team: CKEditor translation team\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+msgid "dir"
+msgstr "ltr"
+
+msgid "editorTitle"
+msgstr ""
+
+msgid "source"
+msgstr "Quellcode"
+
+msgid "newPage"
+msgstr "Neue Seite"
+
+msgid "save"
+msgstr "Speichern"
+
+msgid "preview"
+msgstr "Vorschau"
+
+msgid "common.browseServer"
+msgstr "Server durchsuchen"
+
+msgid "common.url"
+msgstr "Bildauswahl"
+
+msgid "common.protocol"
+msgstr "Protokoll"
+
+msgid "common.confirmCancel"
+msgstr ""
+
+msgid "link.toolbar"
+msgstr "Link einfügen/editieren"
+
+msgid "link.noAnchors"
+msgstr "(keine Anker im Dokument vorhanden)"
+
+#. Error message shown to the user when URL field is empty.
+msgid "link.noUrl"
+msgstr "Bitte geben Sie die Link-URL an"
+
+msgid "link.noEmail"
+msgstr "Bitte geben Sie e-Mail Adresse an"
+
+msgid "table.toolbar"
+msgstr "Tabelle"
+
+msgid "table.cell.menu"
+msgstr "Zelle"
+
+#. Label for the context menu item.
+msgid "table.cell.insertBefore"
+msgstr "Zelle davor einfügen"
+
+msgid "table.row.menu"
+msgstr "Zeile"
+
+msgid "button.typeRst"
+msgstr "Zurücksetzen"
+
Index: /CKLangTool/trunk/test/_assets/gettext/en.js
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/en.js	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/en.js	(revision 7083)
@@ -0,0 +1,89 @@
+﻿/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the English
+ *		language. This is the base file for all translations.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Constains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang['en'] =
+{
+	/**
+	 * The language reading direction. Possible values are "rtl" for
+	 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
+	 * languages (like English).
+	 * @default 'ltr'
+	 */
+	dir : 'ltr',
+
+	/*
+	 * Screenreader titles. Please note that screenreaders are not always capable
+	 * of reading non-English words. So be careful while translating it.
+	 */
+	editorTitle		: 'Rich text editor, %1',
+
+	// Toolbar buttons without dialogs.
+	source			: 'Source',
+	newPage			: 'New Page',
+	save			: 'Save',
+	preview			: 'Preview',
+
+	// Common messages and labels.
+	common :
+	{
+		browseServer	: 'Browser Server',
+		url				: 'URL',
+		protocol		: 'Protocol',
+		confirmCancel	: 'Some of the options have been changed. Are you sure to close the dialog?'
+	},
+
+	// Special char dialog.
+	specialChar		:
+	{
+		toolbar		: 'Insert Special Character',
+		title		: 'Select Special Character'
+	},
+
+	// Link dialog.
+	link :
+	{
+		toolbar		: 'Link\u200b',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
+		noAnchors		: '(No anchors available in the document)',
+		noUrl			: 'Please type the link URL',
+		noEmail			: 'Please type the e-mail address'
+	},
+
+	// Table Dialog
+	table :
+	{
+		toolbar		: 'Table',
+
+		cell :
+		{
+			menu			: 'Cell',
+			insertBefore	: 'Insert Cell Before',
+		},
+
+		row :
+		{
+			menu			: 'Row',
+		},
+	},
+
+	// Button Dialog.
+	button :
+	{
+		typeRst		: 'Reset'
+	},
+};
Index: /CKLangTool/trunk/test/_assets/gettext/en.po.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/en.po.correct.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/en.po.correct.txt	(revision 7083)
@@ -0,0 +1,82 @@
+# Copyright (c) 2003-__CURRENT_YEAR__, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+# Defines the object, for the English language. This is the base file for all translations.
+msgid ""
+msgstr ""
+"Project-Id-Version: CKEditor\n"
+"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\n"
+"POT-Creation-Date: 2011-05-31 00:00+0000\n"
+"PO-Revision-Date: 2011-05-31 00:30+0000\n"
+"Last-Translator: CKEditor\n"
+"Language-Team: CKEditor translation team\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+msgid "dir"
+msgstr "ltr"
+
+msgid "editorTitle"
+msgstr "Rich text editor, %1"
+
+msgid "source"
+msgstr "Source"
+
+msgid "newPage"
+msgstr "New Page"
+
+msgid "save"
+msgstr "Save"
+
+msgid "preview"
+msgstr "Preview"
+
+msgid "common.browseServer"
+msgstr "Browser Server"
+
+msgid "common.url"
+msgstr "URL"
+
+msgid "common.protocol"
+msgstr "Protocol"
+
+msgid "common.confirmCancel"
+msgstr "Some of the options have been changed. Are you sure to close the dialog?"
+
+msgid "specialChar.toolbar"
+msgstr "Insert Special Character"
+
+msgid "specialChar.title"
+msgstr "Select Special Character"
+
+msgid "link.toolbar"
+msgstr "Link​"
+
+msgid "link.noAnchors"
+msgstr "(No anchors available in the document)"
+
+#. Error message shown to the user when URL field is empty.
+msgid "link.noUrl"
+msgstr "Please type the link URL"
+
+msgid "link.noEmail"
+msgstr "Please type the e-mail address"
+
+msgid "table.toolbar"
+msgstr "Table"
+
+msgid "table.cell.menu"
+msgstr "Cell"
+
+#. Label for the context menu item.
+msgid "table.cell.insertBefore"
+msgstr "Insert Cell Before"
+
+msgid "table.row.menu"
+msgstr "Row"
+
+msgid "button.typeRst"
+msgstr "Reset"
+
Index: /CKLangTool/trunk/test/_assets/gettext/meta.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/meta.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/meta.txt	(revision 7083)
@@ -0,0 +1,6 @@
+# Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+# Helper file with additional comments for translators.
+
+link.noUrl = Error message shown to the user when URL field is empty.
+table.cell.insertBefore = Label for the context menu item.
Index: /CKLangTool/trunk/test/_assets/gettext/pl.js
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/pl.js	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/pl.js	(revision 7083)
@@ -0,0 +1,83 @@
+﻿/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Polish language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Constains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang['pl'] =
+{
+	/**
+	 * The language reading direction. Possible values are "rtl" for
+	 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
+	 * languages (like English).
+	 * @default 'ltr'
+	 */
+	dir : 'ltr',
+
+	// Toolbar buttons without dialogs.
+	source			: 'Źródło dokumentu',
+	newPage			: 'Nowa strona',
+	save			: 'Zapisz',
+	preview			: 'Podgląd',
+
+	// Common messages and labels.
+	common :
+	{
+		browseServer	: 'Przeglądaj',
+		url				: 'Adres URL',
+		protocol		: 'Protokół',
+		confirmCancel	: 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING
+	},
+
+	// Special char dialog.
+	specialChar		:
+	{
+		toolbar		: 'Wstaw znak specjalny',
+		title		: 'Wybierz znak specjalny'
+	},
+
+	// Link dialog.
+	link :
+	{
+		toolbar		: 'Wstaw/edytuj hiperłącze',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
+		noAnchors		: '(W dokumencie nie zdefiniowano żadnych etykiet)',
+		noUrl			: 'Podaj adres URL',
+		noEmail			: 'Podaj adres e-mail'
+	},
+
+	// Table Dialog
+	table :
+	{
+		toolbar		: 'Tabela',
+
+		cell :
+		{
+			menu			: 'Komórka',
+			insertBefore	: 'Wstaw komórkę z lewej',
+		},
+
+		row :
+		{
+			menu			: 'Row', // MISSING
+		},
+	},
+
+	// Button Dialog.
+	button :
+	{
+		typeRst		: 'Wyzeruj'
+	},
+};
Index: /CKLangTool/trunk/test/_assets/gettext/pl.po.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/pl.po.correct.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/gettext/pl.po.correct.txt	(revision 7083)
@@ -0,0 +1,79 @@
+# Copyright (c) 2003-__CURRENT_YEAR__, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+# Defines the object, for the Polish language.
+msgid ""
+msgstr ""
+"Project-Id-Version: CKEditor\n"
+"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\n"
+"POT-Creation-Date: 2011-05-31 00:00+0000\n"
+"PO-Revision-Date: 2011-05-31 00:30+0000\n"
+"Last-Translator: CKEditor\n"
+"Language-Team: CKEditor translation team\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+msgid "dir"
+msgstr "ltr"
+
+msgid "source"
+msgstr "Źródło dokumentu"
+
+msgid "newPage"
+msgstr "Nowa strona"
+
+msgid "save"
+msgstr "Zapisz"
+
+msgid "preview"
+msgstr "Podgląd"
+
+msgid "common.browseServer"
+msgstr "Przeglądaj"
+
+msgid "common.url"
+msgstr "Adres URL"
+
+msgid "common.protocol"
+msgstr "Protokół"
+
+msgid "common.confirmCancel"
+msgstr ""
+
+msgid "specialChar.toolbar"
+msgstr "Wstaw znak specjalny"
+
+msgid "specialChar.title"
+msgstr "Wybierz znak specjalny"
+
+msgid "link.toolbar"
+msgstr "Wstaw/edytuj hiperłącze"
+
+msgid "link.noAnchors"
+msgstr "(W dokumencie nie zdefiniowano żadnych etykiet)"
+
+#. Error message shown to the user when URL field is empty.
+msgid "link.noUrl"
+msgstr "Podaj adres URL"
+
+msgid "link.noEmail"
+msgstr "Podaj adres e-mail"
+
+msgid "table.toolbar"
+msgstr "Tabela"
+
+msgid "table.cell.menu"
+msgstr "Komórka"
+
+#. Label for the context menu item.
+msgid "table.cell.insertBefore"
+msgstr "Wstaw komórkę z lewej"
+
+msgid "table.row.menu"
+msgstr ""
+
+msgid "button.typeRst"
+msgstr "Wyzeruj"
+
Index: /CKLangTool/trunk/test/_assets/jprops/de.js
===================================================================
--- /CKLangTool/trunk/test/_assets/jprops/de.js	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/jprops/de.js	(revision 7083)
@@ -0,0 +1,82 @@
+﻿/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * German language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Constains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang['de'] =
+{
+	/**
+	 * The language reading direction. Possible values are "rtl" for
+	 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
+	 * languages (like English).
+	 * @default 'ltr'
+	 */
+	dir : 'ltr',
+
+	/*
+	 * Screenreader titles. Please note that screenreaders are not always capable
+	 * of reading non-English words. So be careful while translating it.
+	 */
+	editorTitle		: 'Rich text editor, %1', // MISSING
+
+	// Toolbar buttons without dialogs.
+	source			: 'Quellcode',
+	newPage			: 'Neue Seite',
+	save			: 'Speichern',
+	preview			: 'Vorschau',
+
+	// Common messages and labels.
+	common :
+	{
+		browseServer	: 'Server durchsuchen',
+		url				: 'Bildauswahl',
+		protocol		: 'Protokoll',
+		confirmCancel	: 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING
+	},
+
+	// Link dialog.
+	link :
+	{
+		toolbar		: 'Link einfügen/editieren',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
+		noAnchors		: '(keine Anker im Dokument vorhanden)',
+		noUrl			: 'Bitte geben Sie die Link-URL an',
+		noEmail			: 'Bitte geben Sie e-Mail Adresse an'
+	},
+
+	// Table Dialog
+	table :
+	{
+		toolbar		: 'Tabelle',
+
+		cell :
+		{
+			menu			: 'Zelle',
+			insertBefore	: 'Zelle davor einfügen',
+		},
+
+		row :
+		{
+			menu			: 'Zeile',
+		},
+	},
+
+	// Button Dialog.
+	button :
+	{
+		typeRst		: 'Zurücksetzen'
+	},
+};
Index: /CKLangTool/trunk/test/_assets/jprops/de.txt.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/jprops/de.txt.correct.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/jprops/de.txt.correct.txt	(revision 7083)
@@ -0,0 +1,24 @@
+# Copyright (c) 2003-__CURRENT_YEAR__, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+
+# Defines the object, for the German language.
+
+dir=ltr
+editorTitle=Rich text editor, %1
+source=Quellcode
+newPage=Neue Seite
+save=Speichern
+preview=Vorschau
+common.browseServer=Server durchsuchen
+common.url=Bildauswahl
+common.protocol=Protokoll
+common.confirmCancel=Some of the options have been changed. Are you sure to close the dialog?
+link.toolbar=Link einfügen/editieren
+link.noAnchors=(keine Anker im Dokument vorhanden)
+link.noUrl=Bitte geben Sie die Link-URL an
+link.noEmail=Bitte geben Sie e-Mail Adresse an
+table.toolbar=Tabelle
+table.cell.menu=Zelle
+table.cell.insertBefore=Zelle davor einfügen
+table.row.menu=Zeile
+button.typeRst=Zurücksetzen
Index: /CKLangTool/trunk/test/_assets/jprops/en.js
===================================================================
--- /CKLangTool/trunk/test/_assets/jprops/en.js	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/jprops/en.js	(revision 7083)
@@ -0,0 +1,89 @@
+﻿/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the English
+ *		language. This is the base file for all translations.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Constains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang['en'] =
+{
+	/**
+	 * The language reading direction. Possible values are "rtl" for
+	 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
+	 * languages (like English).
+	 * @default 'ltr'
+	 */
+	dir : 'ltr',
+
+	/*
+	 * Screenreader titles. Please note that screenreaders are not always capable
+	 * of reading non-English words. So be careful while translating it.
+	 */
+	editorTitle		: 'Rich text editor, %1',
+
+	// Toolbar buttons without dialogs.
+	source			: 'Source',
+	newPage			: 'New Page',
+	save			: 'Save',
+	preview			: 'Preview',
+
+	// Common messages and labels.
+	common :
+	{
+		browseServer	: 'Browser Server',
+		url				: 'URL',
+		protocol		: 'Protocol',
+		confirmCancel	: 'Some of the options have been changed. Are you sure to close the dialog?'
+	},
+
+	// Special char dialog.
+	specialChar		:
+	{
+		toolbar		: 'Insert Special Character',
+		title		: 'Select Special Character'
+	},
+
+	// Link dialog.
+	link :
+	{
+		toolbar		: 'Link\u200b',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
+		noAnchors		: '(No anchors available in the document)',
+		noUrl			: 'Please type the link URL',
+		noEmail			: 'Please type the e-mail address'
+	},
+
+	// Table Dialog
+	table :
+	{
+		toolbar		: 'Table',
+
+		cell :
+		{
+			menu			: 'Cell',
+			insertBefore	: 'Insert Cell Before',
+		},
+
+		row :
+		{
+			menu			: 'Row',
+		},
+	},
+
+	// Button Dialog.
+	button :
+	{
+		typeRst		: 'Reset'
+	},
+};
Index: /CKLangTool/trunk/test/_assets/jprops/en.txt.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/jprops/en.txt.correct.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/jprops/en.txt.correct.txt	(revision 7083)
@@ -0,0 +1,26 @@
+# Copyright (c) 2003-__CURRENT_YEAR__, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+
+# Defines the object, for the English language. This is the base file for all translations.
+
+dir=ltr
+editorTitle=Rich text editor, %1
+source=Source
+newPage=New Page
+save=Save
+preview=Preview
+common.browseServer=Browser Server
+common.url=URL
+common.protocol=Protocol
+common.confirmCancel=Some of the options have been changed. Are you sure to close the dialog?
+specialChar.toolbar=Insert Special Character
+specialChar.title=Select Special Character
+link.toolbar=Link​
+link.noAnchors=(No anchors available in the document)
+link.noUrl=Please type the link URL
+link.noEmail=Please type the e-mail address
+table.toolbar=Table
+table.cell.menu=Cell
+table.cell.insertBefore=Insert Cell Before
+table.row.menu=Row
+button.typeRst=Reset
Index: /CKLangTool/trunk/test/_assets/jprops/pl.js
===================================================================
--- /CKLangTool/trunk/test/_assets/jprops/pl.js	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/jprops/pl.js	(revision 7083)
@@ -0,0 +1,83 @@
+﻿/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Polish language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Constains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang['pl'] =
+{
+	/**
+	 * The language reading direction. Possible values are "rtl" for
+	 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
+	 * languages (like English).
+	 * @default 'ltr'
+	 */
+	dir : 'ltr',
+
+	// Toolbar buttons without dialogs.
+	source			: 'Źródło dokumentu',
+	newPage			: 'Nowa strona',
+	save			: 'Zapisz',
+	preview			: 'Podgląd',
+
+	// Common messages and labels.
+	common :
+	{
+		browseServer	: 'Przeglądaj',
+		url				: 'Adres URL',
+		protocol		: 'Protokół',
+		confirmCancel	: 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING
+	},
+
+	// Special char dialog.
+	specialChar		:
+	{
+		toolbar		: 'Wstaw znak specjalny',
+		title		: 'Wybierz znak specjalny'
+	},
+
+	// Link dialog.
+	link :
+	{
+		toolbar		: 'Wstaw/edytuj hiperłącze',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
+		noAnchors		: '(W dokumencie nie zdefiniowano żadnych etykiet)',
+		noUrl			: 'Podaj adres URL',
+		noEmail			: 'Podaj adres e-mail'
+	},
+
+	// Table Dialog
+	table :
+	{
+		toolbar		: 'Tabela',
+
+		cell :
+		{
+			menu			: 'Komórka',
+			insertBefore	: 'Wstaw komórkę z lewej',
+		},
+
+		row :
+		{
+			menu			: 'Row', // MISSING
+		},
+	},
+
+	// Button Dialog.
+	button :
+	{
+		typeRst		: 'Wyzeruj'
+	},
+};
Index: /CKLangTool/trunk/test/_assets/jprops/pl.txt.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/jprops/pl.txt.correct.txt	(revision 7083)
+++ /CKLangTool/trunk/test/_assets/jprops/pl.txt.correct.txt	(revision 7083)
@@ -0,0 +1,25 @@
+# Copyright (c) 2003-__CURRENT_YEAR__, CKSource - Frederico Knabben. All rights reserved.
+# For licensing, see LICENSE.html or http://ckeditor.com/license
+
+# Defines the object, for the Polish language.
+
+dir=ltr
+source=Źródło dokumentu
+newPage=Nowa strona
+save=Zapisz
+preview=Podgląd
+common.browseServer=Przeglądaj
+common.url=Adres URL
+common.protocol=Protokół
+common.confirmCancel=Some of the options have been changed. Are you sure to close the dialog?
+specialChar.toolbar=Wstaw znak specjalny
+specialChar.title=Wybierz znak specjalny
+link.toolbar=Wstaw/edytuj hiperłącze
+link.noAnchors=(W dokumencie nie zdefiniowano żadnych etykiet)
+link.noUrl=Podaj adres URL
+link.noEmail=Podaj adres e-mail
+table.toolbar=Tabela
+table.cell.menu=Komórka
+table.cell.insertBefore=Wstaw komórkę z lewej
+table.row.menu=Row
+button.typeRst=Wyzeruj
Index: /CKLangTool/trunk/test/test.js
===================================================================
--- /CKLangTool/trunk/test/test.js	(revision 7082)
+++ /CKLangTool/trunk/test/test.js	(revision 7083)
@@ -8,5 +8,5 @@
 	// Run tests.
 	var passCount = 0, failCount = 0;
-	CKLANGTOOL.metafilePath = '_assets/poformat/meta.txt';
+	CKLANGTOOL.metaFile = '_assets/gettext/meta.txt';
 
 	function deleteDirectory( path )
@@ -51,5 +51,13 @@
 		}
 	}	
-	
+
+	function normalizeDate( content )
+	{
+		var fullYear = new Date().getFullYear();
+		return content.replace( /__CURRENT_YEAR__/g, fullYear )
+			.replace(/"PO-Revision-Date:.*?"/g,'' )
+			.replace(/"POT-Creation-Date:.*?"/g,'' );
+	}
+
 	function assertEquals( expected, actual, title )
 	{
@@ -91,5 +99,5 @@
 			error( "Can't create temp directory: " + tempDir );
 
-		var tests = [ 'poformat', 'poformat/out', 'jpformat', 'jpformat/out', 'translator' ];
+		var tests = [ 'gettext', 'gettext/out', 'jprops', 'jprops/out', 'translator' ];
 
 		for ( var i = 0 ; i < tests.length ; i++ )
@@ -115,5 +123,5 @@
 
 		var translator = new CKLANGTOOL.translator();
-		translator.run();
+		translator.run( CKLANGTOOL.languageDir );
 
 		dirList = CKLANGTOOL.languageDir.list();
@@ -138,10 +146,10 @@
 	function testFormat( format )
 	{
-		var tmpDir = 'tmp/' + format + 'format';
+		var tmpDir = 'tmp/' + format;
 		CKLANGTOOL.languageDir = new File( tmpDir );
 		CKLANGTOOL.destinationDir = new File( tmpDir + '/out' );
 		CKLANGTOOL.templateFile = new File( tmpDir, 'en.js' );
 		
-		var dir = new File( '_assets/' + format + 'format' );
+		var dir = new File( '_assets/' + format );
 		var dirList = dir.list();
 		
@@ -152,5 +160,5 @@
 		}
 
-		var formatter = new CKLANGTOOL[format + 'format']();
+		var formatter = new CKLANGTOOL[format]();
 		formatter.run();
 
@@ -168,7 +176,5 @@
 			correctFile = new File( tmpDir, testName + '.correct.txt' );
 			
-			var date = new Date(),
-				fullYear = date.getFullYear();
-			assertEquals( CKLANGTOOL.io.readFile( correctFile ).replace( /__CURRENT_YEAR__/g, fullYear ), CKLANGTOOL.io.readFile( tempFile ));
+			assertEquals( normalizeDate( CKLANGTOOL.io.readFile( correctFile ) ), normalizeDate( CKLANGTOOL.io.readFile( tempFile ) ) );
 		}
 	}
@@ -176,6 +182,6 @@
 	prepareTempDirs();
 	testTranslator();
-	testFormat('po');
-	testFormat('jp');
+	testFormat('gettext');
+	testFormat('jprops');
 
 	print( '' );
