Ticket #7983: 7983_2.patch

File 7983_2.patch, 10.5 KB (added by Garry Yao, 13 years ago)
  • _source/langtool.js

     
    5353
    5454CKLANGTOOL.isCompiled = isCompiled;
    5555CKLANGTOOL.load( 'cklangtool.includes.ckjpformat' );
     56CKLANGTOOL.load( 'cklangtool.includes.ckpoformat' );
    5657CKLANGTOOL.load( 'cklangtool.includes.io' );
    5758
    5859if ( !arguments[0] || arguments[0] == '-help' || arguments[0] == '/?' )
    59         error( 'Usage: ' + command + ' lang_dir [-jpformat=dest_dir]'
     60        error( 'Usage: ' + command + ' lang_dir [-jpformat=dest_dir]|[-poformat=dest_dir]'
    6061                        + '\n\n CKLangTool corrects translation files and creates report about missing translations.'
    61                         + '\n\n -jpformat  Convert files to java properties format and save them in dest_dir.\n' );
     62                        + '\n\n -jpformat  Convert files to java properties format and save them in dest_dir'
     63                        + '\n\n -poformat  Convert files to GNU gettext PO format and save them in dest_dir.\n' );
    6264
    6365for ( var i = 0 ; i < arguments.length ; i++ )
    6466{
    65         if ( arguments[i].indexOf( "-jpformat=" ) != -1 )
     67        var arg = arguments[i], match;
     68        if ( match = arg.match( /^-(\w+format)=(.*?)$/ ) )
    6669        {
    67                 var destDir = arguments[i].substring( arguments[i].indexOf( "=" ) + 1 );
     70                var destDir = match[ 2 ];
    6871                CKLANGTOOL.destinationDir = new File( destDir );
    6972                if ( CKLANGTOOL.destinationDir.exists() )
    70                         error( 'Destination directory already exists: ' + CKLANGTOOL.destinationDir.getAbsolutePath() );
     73                {
     74                        print( 'Remove directory already exists: ' + CKLANGTOOL.destinationDir.getAbsolutePath() );
     75                        CKLANGTOOL.destinationDir[ 'delete' ]();
     76                }
    7177                else
    7278                        CKLANGTOOL.destinationDir.mkdir();
    73                 CKLANGTOOL.operation = "jpformat";
     79                CKLANGTOOL.format = match[ 1 ];
    7480        }
    7581}
    7682
     
    98104{
    99105        try
    100106        {
    101                 if ( CKLANGTOOL.operation == "jpformat" )
     107                // Convert or sync languages files from other format.
     108                if ( CKLANGTOOL.format )
    102109                {
    103                         var jpformat = new CKLANGTOOL.jpformat();
    104                         jpformat.run();
     110                        var format = new CKLANGTOOL[ CKLANGTOOL.format ]();
     111                        format.run();
    105112                }
    106113                else
    107114                {
  • _source/includes/cklangtool.js

     
    1010        isCompiled : false,
    1111        languageDir : "",
    1212        templateFile : "",
    13         operation : "default",
     13        format : "default",
    1414        /**
    1515         * Holds the content of en.js language file where strings are replaced with
    1616         * special placeholders: #ckeditor_translation.placeholder.key#.
     
    3737
    3838/**
    3939 * Load language file and return an object with the whole translation.
     40 * @param {Boolean} translatedOnly When set to true will ignore all entries that are marked as missing.
    4041 */
    41 CKLANGTOOL.loadLanguageFile = function( file )
     42CKLANGTOOL.loadLanguageFile = function( file, translatedOnly )
    4243{
    43         var translationCode = 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file );
     44        var content = CKLANGTOOL.io.readFile( file );
    4445
     46        // Dismiss line marked by comment marker - MISSING.
     47        if( translatedOnly )
     48                content = content.replace( /^.*\/\/ MISSING$/gm, '' );
     49
     50        var translationCode = 'var CKEDITOR = { lang : {} }; ' + content;
     51
    4552        var cx = Context.enter(), scope = cx.initStandardObjects();
    4653
    4754        try
     
    266273         * #ckeditor_translation.__fileOverview# (the block comment with the file
    267274         * description)
    268275         */
    269         function createTemplate( file )
     276        CKLANGTOOL.translator.createTemplate = function( file )
    270277        {
    271278                var key = "ckeditor_translation";
    272279                var out = [];
     
    427434         * If translation contains dots, for example: common.textField then return
    428435         * translation[common][textfield]
    429436         */
    430         function getTranslation( translation, translationKey )
     437        CKLANGTOOL.translator.getTranslation = function( translation, translationKey )
    431438        {
    432439                var dotPos;
    433440                var result = translation;
     
    507514                         * #ckeditor_translation.common.textField# -> common.textField
    508515                         */
    509516                        translationKey = matchResult.group( 0 ).slice( 22, -1 );
    510                         replacement = getTranslation( translation, translationKey );
     517                        replacement = CKLANGTOOL.translator.getTranslation( translation, translationKey );
    511518
    512519                        /*
    513520                         * common.textField[1] -> common.textField
     
    518525                                 * FoldersTitle : '#ckeditor_translation.FoldersTitle#', ->
    519526                                 * FoldersTitle : '[MISSING_TRANSLATION]Folders',
    520527                                 */
    521                                 replacement = "[MISSING_TRANSLATION]" + getTranslation( CKLANGTOOL.englishTranslation, translationKey );
     528                                replacement = "[MISSING_TRANSLATION]" + CKLANGTOOL.translator.getTranslation( CKLANGTOOL.englishTranslation, translationKey );
    522529                                string = (string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ));
    523530
    524531                                if ( translationKey.substring( 0, 2 ) != "__" )
     
    576583        {
    577584                run : function()
    578585                {
    579                         CKLANGTOOL.template = createTemplate( CKLANGTOOL.templateFile );
     586                        CKLANGTOOL.template = CKLANGTOOL.translator.createTemplate( CKLANGTOOL.templateFile );
    580587                        var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile );
    581588                        CKLANGTOOL.englishTranslation = result.translation;
    582589
  • _source/includes/ckpoformat.js

     
     1/*
     2Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6importPackage( java.util.regex );
     7
     8( function()
     9{
     10        CKLANGTOOL.poformat = function()
     11        {
     12                return {
     13                        run : function()
     14                        {
     15                                var children = CKLANGTOOL.languageDir.list();
     16                                var file, poFile;
     17                                var foundFiles = false;
     18
     19                                for ( var i = 0 ; i < children.length ; i++ )
     20                                {
     21                                        if ( CKLANGTOOL.io.getExtension( children[ i ] ) != "js" || children[ i ].indexOf( '_' ) == 0 )
     22                                                continue;
     23
     24                                        file = new File( CKLANGTOOL.languageDir, children[ i ] );
     25                                        if ( file.isFile() )
     26                                        {
     27                                                poFile =  new File( CKLANGTOOL.destinationDir, children[i].replaceAll( '.js', '.po' ) );
     28                                                print( "Processing " + file.getAbsolutePath() );
     29
     30                                                CKLANGTOOL.io.saveFile( poFile, processFile(file), false );
     31                                                foundFiles = true;
     32                                        }
     33                                }
     34
     35                                if ( !foundFiles )
     36                                {
     37                                        print( "WARNING: language files not found." );
     38                                }
     39
     40                                print( "Process completed." );
     41                        }
     42                };
     43        };
     44
     45        /**
     46         * Language code of currently processed file (taken from
     47         * CKEDITOR.lang['code']).
     48         */
     49        var fileOverviewBlock;
     50
     51        function printObject( prefix, o )
     52        {
     53                var result = [];
     54
     55                for ( var key in o )
     56                {
     57                        var entry = o[ key ],
     58                                entryName = prefix ? ( prefix + '.' + key ) : key;
     59
     60                        if ( typeof entry == 'object' )
     61                                result.push( printObject( entryName, entry ) );
     62                        else
     63                                result.push( poEntry( entryName, entry ) );
     64                }
     65               
     66                return result.join( '' );
     67        }
     68
     69        function msgstrEscape( str )
     70        {
     71                return str.replace( /"/g, '\\"' ).replace( /\r\n|\n/g, '\\n"$&"' );
     72        }
     73
     74        /**
     75         *  Generate a PO translation entry with the following schematic structure:
     76         *      whte-space
     77         *      # translator-comments
     78         *      #.extracted-comments
     79         *      #:reference...
     80         *      #,flag...
     81         *      #|msgid previous-untranslated-string
     82         *      msid untranslated-string
     83         *      msstr translated-string
     84         *
     85         * @param {String} id The untranslated string part.
     86         * @param {String} str The translated-string part.
     87         * @param {String} [ comment1, comment2... ] Translator comments.
     88         */
     89        function poEntry( id, str, comment )
     90        {
     91                var entry = [];
     92                var comments = Array.prototype.slice.call( arguments, 2 );
     93                for ( var i = 0; i < comments.length; i++ )
     94                        entry.push( comments[ i ] );
     95                entry.push( 'msgid "' + id + '"', 'msgstr "' + msgstrEscape( str ) + '"', '\n' );
     96                return entry.join( '\n' );
     97        }
     98
     99        function poHeader()
     100        {
     101                return [
     102                '"Project-Id-Version: CKEditor\\n"',
     103                '"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\\n"',
     104                '"POT-Creation-Date: 2011-05-31 00:00+0000\\n"',
     105                '"PO-Revision-Date: 2011-05-31 00:30+0000\\n"',
     106                '"Last-Translator: CKEditor\\n"',
     107                '"Language-Team: CKEditor translation team\\n"',
     108                '"MIME-Version: 1.0\\n"',
     109                '"Content-Type: text/plain; charset=UTF-8\\n"',
     110                '"Content-Transfer-Encoding: 8bit\\n"',
     111                '"Language: en\\n"',
     112                '"Plural-Forms: nplurals=2; plural=(n != 1)\\n"',
     113                '\n'
     114                ].join( '\n' );
     115        }
     116       
     117        function processFile( file )
     118        {
     119                // License Info
     120                var license = '# Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\n# For licensing, see LICENSE.html or http://ckeditor.com/license';
     121                var overview = getFileOverview( file.getAbsolutePath() ).replace( /\{.*?\}/g, '' ).replace( /@fileOverview/g, '' ).replace(/\s*(\/)?\s*(\*)+(\/)?/g , '').replace(/\s+/g, ' ');
     122
     123                // File Overview
     124                var language = CKLANGTOOL.loadLanguageFile( file, true );
     125                return poEntry( '', '', license, overview ) + poHeader() + printObject( '', language.translation );
     126        }
     127
     128        var regexLib =
     129        {
     130                inlineComment :Pattern.compile( "^\\s*\\/\\/" ),
     131                blockCommentStart :Pattern.compile( "\\/\\*" ),
     132                blockCommentEnd :Pattern.compile( "\\*\\/" ),
     133                fileOverview :Pattern.compile( " @fileOverview" )
     134        };
     135       
     136        /**
     137         * Returns an array with missing keys (already marked as //MISSING).
     138         */
     139        function getFileOverview( file )
     140        {
     141                fileOverviewBlock = '/**\n* @fileOverview \n*/';
     142
     143                var inBlockComment = false;
     144                var blockComment = [];
     145                var matcher, line;
     146                var lines = CKLANGTOOL.io.readFileIntoArray( file );
     147
     148                for ( var j = 0 ; j < lines.length ; j++ )
     149                {
     150                        line = lines[ j ];
     151                        if ( !inBlockComment )
     152                        {
     153                                matcher = regexLib.inlineComment.matcher( line );
     154                                if ( matcher.find() )
     155                                        continue;
     156
     157                                matcher = regexLib.blockCommentStart.matcher( line );
     158                                if ( matcher.find() )
     159                                {
     160                                        inBlockComment = true;
     161                                        blockComment.push( line );
     162                                        continue;
     163                                }
     164                        }
     165                        else
     166                        {
     167                                blockComment.push( line );
     168
     169                                matcher = regexLib.blockCommentEnd.matcher( line );
     170                                if ( matcher.find() )
     171                                {
     172                                        inBlockComment = false;
     173
     174                                        matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) );
     175                                        if ( matcher.find() )
     176                                                fileOverviewBlock = blockComment.join( "\n" );
     177                                        blockComment = [];
     178                                }
     179                        }
     180                }
     181
     182                return '#' + fileOverviewBlock;
     183        }
     184       
     185})();
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy