Ticket #7983: 7983.patch

File 7983.patch, 10.4 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#.
     
    266266         * #ckeditor_translation.__fileOverview# (the block comment with the file
    267267         * description)
    268268         */
    269         function createTemplate( file )
     269        CKLANGTOOL.translator.createTemplate = function( file )
    270270        {
    271271                var key = "ckeditor_translation";
    272272                var out = [];
     
    427427         * If translation contains dots, for example: common.textField then return
    428428         * translation[common][textfield]
    429429         */
    430         function getTranslation( translation, translationKey )
     430        CKLANGTOOL.translator.getTranslation = function( translation, translationKey )
    431431        {
    432432                var dotPos;
    433433                var result = translation;
     
    507507                         * #ckeditor_translation.common.textField# -> common.textField
    508508                         */
    509509                        translationKey = matchResult.group( 0 ).slice( 22, -1 );
    510                         replacement = getTranslation( translation, translationKey );
     510                        replacement = CKLANGTOOL.translator.getTranslation( translation, translationKey );
    511511
    512512                        /*
    513513                         * common.textField[1] -> common.textField
     
    518518                                 * FoldersTitle : '#ckeditor_translation.FoldersTitle#', ->
    519519                                 * FoldersTitle : '[MISSING_TRANSLATION]Folders',
    520520                                 */
    521                                 replacement = "[MISSING_TRANSLATION]" + getTranslation( CKLANGTOOL.englishTranslation, translationKey );
     521                                replacement = "[MISSING_TRANSLATION]" + CKLANGTOOL.translator.getTranslation( CKLANGTOOL.englishTranslation, translationKey );
    522522                                string = (string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ));
    523523
    524524                                if ( translationKey.substring( 0, 2 ) != "__" )
     
    576576        {
    577577                run : function()
    578578                {
    579                         CKLANGTOOL.template = createTemplate( CKLANGTOOL.templateFile );
     579                        CKLANGTOOL.template = CKLANGTOOL.translator.createTemplate( CKLANGTOOL.templateFile );
    580580                        var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile );
    581581                        CKLANGTOOL.englishTranslation = result.translation;
    582582
  • _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        /**
     52         * Check whether the specified transaction value is
     53         * actually the source language but not a translation.
     54         * @param key
     55         * @param entry
     56         */
     57        function checkEntryMissing( key, entry )
     58        {
     59                if ( !CKLANGTOOL.englishTranslation )
     60                {
     61                        CKLANGTOOL.template = CKLANGTOOL.translator.createTemplate( CKLANGTOOL.templateFile );
     62                        var tpl = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile );
     63                        CKLANGTOOL.englishTranslation = tpl.translation;
     64                }
     65               
     66                return entry == CKLANGTOOL.translator.getTranslation( CKLANGTOOL.englishTranslation, key );
     67        }
     68
     69        function printObject( prefix, o, langCode )
     70        {
     71                var result = [];
     72
     73                for ( var key in o )
     74                {
     75                        var entry = o[ key ],
     76                                entryName = prefix ? ( prefix + '.' + key ) : key;
     77
     78                        if ( typeof entry == 'object' )
     79                                result.push( printObject( entryName, entry, langCode ) );
     80                        else if( langCode == 'en' || !checkEntryMissing( entryName, entry ) )   // Strip missing translation entries.
     81                                result.push( poEntry( entryName, entry ) );
     82                }
     83               
     84                return result.join( '' );
     85        }
     86
     87        function msgstrEscape( str )
     88        {
     89                return str.replace( /"/g, '\\"' ).replace( /\r\n|\n/g, '\\n"$&"' );
     90        }
     91
     92        /**
     93         *  Generate a PO translation entry with the following schematic structure:
     94         *      whte-space
     95         *      # translator-comments
     96         *      #.extracted-comments
     97         *      #:reference...
     98         *      #,flag...
     99         *      #|msgid previous-untranslated-string
     100         *      msid untranslated-string
     101         *      msstr translated-string
     102         *
     103         * @param {String} id The untranslated string part.
     104         * @param {String} str The translated-string part.
     105         * @param {String} [ comment1, comment2... ] Translator comments.
     106         */
     107        function poEntry( id, str, comment )
     108        {
     109                var entry = [];
     110                var comments = Array.prototype.slice.call( arguments, 2 );
     111                for ( var i = 0; i < comments.length; i++ )
     112                        entry.push( comments[ i ] );
     113                entry.push( 'msgid "' + id + '"', 'msgstr "' + msgstrEscape( str ) + '"', '\n' );
     114                return entry.join( '\n' );
     115        }
     116
     117        function poHeader()
     118        {
     119                return [
     120                '"Project-Id-Version: CKEditor\\n"',
     121                '"Report-Msgid-Bugs-To: http://dev.ckeditor.com/newticket\\n"',
     122                '"POT-Creation-Date: 2011-05-31 00:00+0000\\n"',
     123                '"PO-Revision-Date: 2011-05-31 00:30+0000\\n"',
     124                '"Last-Translator: CKEditor\\n"',
     125                '"Language-Team: CKEditor translation team\\n"',
     126                '"MIME-Version: 1.0\\n"',
     127                '"Content-Type: text/plain; charset=UTF-8\\n"',
     128                '"Content-Transfer-Encoding: 8bit\\n"',
     129                '"Language: en\\n"',
     130                '"Plural-Forms: nplurals=2; plural=(n != 1)\\n"',
     131                '\n'
     132                ].join( '\n' );
     133        }
     134       
     135        function processFile( file )
     136        {
     137                // License Info
     138                var license = '# Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\n# For licensing, see LICENSE.html or http://ckeditor.com/license';
     139                var overview = getFileOverview( file.getAbsolutePath() ).replace( /\{.*?\}/g, '' ).replace( /@fileOverview/g, '' ).replace(/\s*(\/)?\s*(\*)+(\/)?/g , '').replace(/\s+/g, ' ');
     140
     141                // File Overview
     142                var language = CKLANGTOOL.loadLanguageFile( file );
     143                return poEntry( '', '', license, overview ) + poHeader() + printObject( '', language.translation, language.languageCode );
     144        }
     145
     146        var regexLib =
     147        {
     148                inlineComment :Pattern.compile( "^\\s*\\/\\/" ),
     149                blockCommentStart :Pattern.compile( "\\/\\*" ),
     150                blockCommentEnd :Pattern.compile( "\\*\\/" ),
     151                fileOverview :Pattern.compile( " @fileOverview" )
     152        };
     153       
     154        /**
     155         * Returns an array with missing keys (already marked as //MISSING).
     156         */
     157        function getFileOverview( file )
     158        {
     159                fileOverviewBlock = '/**\n* @fileOverview \n*/';
     160
     161                var inBlockComment = false;
     162                var blockComment = [];
     163                var matcher, line;
     164                var lines = CKLANGTOOL.io.readFileIntoArray( file );
     165
     166                for ( var j = 0 ; j < lines.length ; j++ )
     167                {
     168                        line = lines[ j ];
     169                        if ( !inBlockComment )
     170                        {
     171                                matcher = regexLib.inlineComment.matcher( line );
     172                                if ( matcher.find() )
     173                                        continue;
     174
     175                                matcher = regexLib.blockCommentStart.matcher( line );
     176                                if ( matcher.find() )
     177                                {
     178                                        inBlockComment = true;
     179                                        blockComment.push( line );
     180                                        continue;
     181                                }
     182                        }
     183                        else
     184                        {
     185                                blockComment.push( line );
     186
     187                                matcher = regexLib.blockCommentEnd.matcher( line );
     188                                if ( matcher.find() )
     189                                {
     190                                        inBlockComment = false;
     191
     192                                        matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) );
     193                                        if ( matcher.find() )
     194                                                fileOverviewBlock = blockComment.join( "\n" );
     195                                        blockComment = [];
     196                                }
     197                        }
     198                }
     199
     200                return '#' + fileOverviewBlock;
     201        }
     202       
     203})();
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy