Ticket #3698: 3698.patch
File 3698.patch, 38.8 KB (added by , 16 years ago) |
---|
-
_source/includes/cklangtool.js
11 11 languageDir : "", 12 12 templateFile : "", 13 13 operation : "default", 14 EOL : '\r\n', 14 15 /** 15 16 * Holds the content of en.js language file where strings are replaced with 16 17 * special placeholders: #ckeditor_translation.placeholder.key#. 17 18 */ 18 19 template : "", 19 20 path : "", 20 21 header : "Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r\nFor licensing, see LICENSE.html or http://ckeditor.com/license", 22 21 23 load : function( className ) 22 24 { 23 25 if ( CKLANGTOOL.isCompiled ) … … 32 34 33 35 load( CKLANGTOOL.path + path ); 34 36 } 35 } 37 } 36 38 }; 37 39 38 40 /** … … 71 73 for ( var i in scope ) 72 74 { 73 75 if ( i != "CKEDITOR" ) 74 return { 'languageCode' : languageCode, 'translation' : scope[i] };76 return { 'languageCode' : languageCode, 'translation' : scope[i], 'type' : 'other' }; 75 77 } 76 78 } 77 79 else … … 82 84 for ( var i in scope.CKEDITOR.lang ) 83 85 { 84 86 languageCode = i; 85 return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i] };87 return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i], 'type' : 'CKEditor' }; 86 88 } 87 89 } 88 90 } … … 96 98 { 97 99 CKLANGTOOL.translator = function() 98 100 { 99 CKLANGTOOL.englishTranslation = 100 {}; 101 CKLANGTOOL.englishTranslation = {}; 101 102 }; 102 103 103 104 /** … … 123 124 } 124 125 catch ( e ) 125 126 { 126 throw ( "Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message);127 throw ( "Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message ); 127 128 } 128 129 } 129 130 130 131 var regexLib = 131 132 { 132 inlineComment :Pattern.compile( "^\\s*\\/\\/" ), 133 missing :Pattern.compile( "\\/\\/\\s*MISSING", Pattern.CASE_INSENSITIVE ), 134 blockCommentStart :Pattern.compile( "\\/\\*" ), 135 blockCommentEnd :Pattern.compile( "\\*\\/" ), 136 entry :Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\').*?(\\'.*)$", Pattern.CASE_INSENSITIVE ), 137 arrayEntry :Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\[)(.*?)(\\].*)$", Pattern.CASE_INSENSITIVE ), 138 arrayItemEntry :Pattern.compile( "\\s*(?:'(.*?)'(?:\\s*,\\s*)?)" ), 139 arrayTranslationKey :Pattern.compile( "^(.*)\\[(\\d+)\\]$" ), 140 objectName :Pattern.compile( "^\\s*([a-z][_a-z0-9]*)\\s*:\\s*$", Pattern.CASE_INSENSITIVE ), 141 objectStart :Pattern.compile( "\\{" ), 142 objectEnd :Pattern.compile( "\\}" ), 143 fileOverview :Pattern.compile( " @fileOverview" ), 144 translation :Pattern.compile( "#ckeditor_translation[^#]*?#" ), 145 ckeditorLang :Pattern.compile( "(.*CKEDITOR\\.lang\\[).*?(\\]\\s*=.*)" ) 133 inlineComment : Pattern.compile( "^\\s*\\/\\/" ), 134 inlineCommentAtTheEndOfLine : Pattern.compile( "\\S+\\s*(\\/\\/.*)$" ), 135 missing : Pattern.compile( "\\/\\/\\s*MISSING", Pattern.CASE_INSENSITIVE ), 136 blockCommentStart : Pattern.compile( "\\/\\*" ), 137 blockCommentEnd : Pattern.compile( "\\*\\/" ), 138 entry : Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\').*?(\\'.*)$", Pattern.CASE_INSENSITIVE ), 139 arrayEntry : Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\[)(.*?)(\\].*)$", Pattern.CASE_INSENSITIVE ), 140 arrayItemEntry : Pattern.compile( "\\s*(?:'(.*?)'(?:\\s*,\\s*)?)" ), 141 arrayTranslationKey : Pattern.compile( "^(.*)\\[(\\d+)\\]$" ), 142 objectName : Pattern.compile( "^\\s*([a-z][_a-z0-9]*)\\s*:\\s*(:?\\/\\/.*)?$", Pattern.CASE_INSENSITIVE ), 143 objectStart : Pattern.compile( "\\{" ), 144 objectEnd : Pattern.compile( "\\}" ), 145 fileOverview : Pattern.compile( " @fileOverview" ), 146 copyright : Pattern.compile( "Copyright" ), 147 translation : Pattern.compile( "#ckeditor_translation[^#]*?#" ), 148 ckeditorLang : Pattern.compile( "(.*CKEDITOR\\.lang\\[).*?(\\]\\s*=.*)" ) 146 149 }; 147 150 148 151 /** … … 150 153 */ 151 154 function analyzeLanguageFile( file ) 152 155 { 153 fileOverviewBlock = '/** \n* @fileOverview \n*/';156 fileOverviewBlock = '/**' + CKLANGTOOL.EOL + '* @fileOverview ' + CKLANGTOOL.EOL + '*/'; 154 157 155 158 var key = "ckeditor_translation"; 156 var out = 157 {}; 159 var out = {}; 158 160 var inBlockComment = false; 159 161 var blockComment = []; 160 162 var objectName, matcher, line, translationKey; … … 162 164 163 165 for ( var j = 0 ; j < lines.length ; j++ ) 164 166 { 165 line = lines[ j];167 line = lines[j]; 166 168 if ( !inBlockComment ) 167 169 { 168 170 matcher = regexLib.inlineComment.matcher( line ); … … 218 220 { 219 221 translationKey = key + "." + matcher.group( 2 ); 220 222 translationKey = translationKey.replace( /^ckeditor_translation\./, "" ); 221 out[ translationKey] = true;223 out[translationKey] = true; 222 224 } 223 225 224 226 /* … … 229 231 { 230 232 translationKey = key + "." + matcher.group( 2 ); 231 233 translationKey = translationKey.replace( /^ckeditor_translation\./, "" ); 232 out[ translationKey] = true;234 out[translationKey] = true; 233 235 } 234 236 } 235 237 else … … 244 246 matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) ); 245 247 if ( matcher.find() ) 246 248 { 247 fileOverviewBlock = blockComment.join( "\n");249 fileOverviewBlock = blockComment.join( CKLANGTOOL.EOL ); 248 250 } 249 251 blockComment = []; 250 252 } … … 265 267 * 266 268 * #ckeditor_translation.__fileOverview# (the block comment with the file 267 269 * description) 268 270 */ 269 271 function createTemplate( file ) 270 272 { 271 var key = "ckeditor_translation"; 272 var out = []; 273 var o = CKLANGTOOL.loadLanguageFile( file ); 274 var comments = loadComments( file ); 275 var template = '/*' + CKLANGTOOL.EOL + CKLANGTOOL.header + CKLANGTOOL.EOL + '*/' + CKLANGTOOL.EOL; 276 277 for ( var i = 0 ; i < comments['_'].length ; i++ ) 278 template = template + CKLANGTOOL.EOL + comments['_'][i] + CKLANGTOOL.EOL; 279 280 if ( o.type == 'CKEditor' ) 281 { 282 template = template + "CKEDITOR.lang['#ckeditor_translation.__languageCode#'] =" + CKLANGTOOL.EOL + "{" + CKLANGTOOL.EOL 283 + outObject( o.translation, "ckeditor_translation", comments, '\t' ) + CKLANGTOOL.EOL + '};' + CKLANGTOOL.EOL; 284 } 285 else 286 template += outObject( o.translation, "ckeditor_translation", comments, '' ); 287 288 /** 289 * Uncomment this line to see the template. 290 */ 291 // CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "template.txt" ), template, false ); 292 return template; 293 } 294 295 var outString = function( str ) 296 { 297 var value = String( str ), 298 singleParts = value.split( "'" ), 299 doubleParts = value.split( '"' ); 300 301 value = value.replace( /[\b\t\n\v\f\r\x1b\xa0\\]/g, function( match ) 302 { 303 var chars = 304 { 305 '\b' : '\\b', 306 '\t' : '\\t', 307 '\n' : '\\n', 308 '\v' : '\\v', 309 '\f' : '\\f', 310 '\r' : '\\r', 311 '\\' : '\\\\', 312 '\x1b' : '\\x1b', 313 '\xa0' : '\\xa0' 314 }; 315 316 return chars[ match ]; 317 } ); 318 319 if ( doubleParts.length > singleParts.length ) 320 return "'" + value.replace( /'/g, "\\'" ) + "'" ; 321 else if ( singleParts.length > 1 ) 322 return '"' + value.replace( /"/g, '\\"' ) + '"' ; 323 else 324 return "'" + value + "'" ; 325 }; 326 327 function loadComments( file ) 328 { 329 var comments = { '_' : [], '_eol' : [] }; 330 var commentWaiting = false; 331 332 var tempKey, key = "ckeditor_translation"; 273 333 var inBlockComment = false; 274 var blockComment = []; 275 var i, matcher, matchResult, objectName, string, line; 276 var arrayEntryItems, arrayEntryItemsMatcher, arrayEntryLineEnd, arrayEntryLine, arrayEntryKey; 334 var inlineCommentAtTheEndOfLine, blockComment = []; 335 var arrayEntryKey, i, line, matcher, objectName; 277 336 var lines = CKLANGTOOL.io.readFileIntoArray( file ); 278 337 279 338 for ( var j = 0 ; j < lines.length ; j++ ) 280 339 { 281 line = lines[ j];340 line = lines[j]; 282 341 283 342 if ( !inBlockComment ) 284 343 { 285 344 matcher = regexLib.inlineComment.matcher( line ); 286 345 if ( matcher.find() ) 287 346 { 288 out.push( line ); 347 if ( commentWaiting !== false ) 348 commentWaiting = commentWaiting + CKLANGTOOL.EOL + line.replace( '\t', '' ); 349 else 350 commentWaiting = line.replace( '\t', '' ); 289 351 continue; 290 352 } 291 353 292 354 matcher = regexLib.blockCommentStart.matcher( line ); 293 355 if ( matcher.find() ) 294 356 { 357 blockComment.push( line.replace( '\t', '' ) ); 295 358 inBlockComment = true; 296 blockComment.push( line );297 359 continue; 298 360 } 299 361 … … 301 363 if ( matcher.find() ) 302 364 { 303 365 objectName = matcher.group( 1 ); 304 out.push( line ); 366 367 matcher = regexLib.inlineCommentAtTheEndOfLine.matcher( line ); 368 if ( matcher.find() ) 369 comments['_eol'][key + "." + objectName] = matcher.group( 1 ); 370 305 371 continue; 306 372 } 307 373 308 374 if ( objectName ) 309 375 { 376 matcher = regexLib.inlineCommentAtTheEndOfLine.matcher( line ); 377 if ( matcher.find() ) 378 inlineCommentAtTheEndOfLine = matcher.group( 1 ); 379 else 380 inlineCommentAtTheEndOfLine = false; 381 310 382 matcher = regexLib.objectStart.matcher( line ); 311 383 /* 312 384 * We have found an opening bracket, key -> key.objectName … … 314 386 if ( matcher.find() ) 315 387 { 316 388 key = key + "." + objectName; 317 out.push( line ); 389 390 if ( commentWaiting !== false ) 391 { 392 comments[key] = commentWaiting; 393 commentWaiting = false; 394 } 395 396 if ( inlineCommentAtTheEndOfLine !== false ) 397 comments['_eol'][key + "_1"] = inlineCommentAtTheEndOfLine; 398 318 399 continue; 319 400 } 401 else 402 { 403 tempKey = key; 320 404 405 matcher = regexLib.entry.matcher( line.replaceAll( "\\\\'", "" ) ); 406 if ( matcher.find() ) 407 tempKey = key + "." + matcher.group( 2 ); 408 409 if ( inlineCommentAtTheEndOfLine !== false ) 410 comments['_eol'][tempKey] = inlineCommentAtTheEndOfLine; 411 412 if ( commentWaiting !== false ) 413 { 414 comments[tempKey] = commentWaiting; 415 commentWaiting = false; 416 } 417 } 418 321 419 matcher = regexLib.objectEnd.matcher( line ); 322 420 /* 323 421 * We have found a closing bracket, key.objectName -> key … … 325 423 if ( matcher.find() ) 326 424 { 327 425 key = key.slice( 0, key.lastIndexOf( "." ) ); 328 out.push( line );329 426 continue; 330 427 } 331 428 } 332 429 333 /* 334 * Find CKEDITOR.lang['en'] 335 */ 336 matcher = regexLib.ckeditorLang.matcher( line ); 337 if ( matcher.find() ) 430 if ( commentWaiting !== false ) 338 431 { 339 out.push( matcher.group( 1 ) + "'#ckeditor_translation.__languageCode#'" + matcher.group( 2 ) ); 340 continue; 341 } 432 /* 433 * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key. 434 * We're changing here the entry into the key. 435 * So 'Upload' becomes '#ckeditor_translation.Upload#' in our temporary template. 436 */ 437 matcher = regexLib.entry.matcher( line.replaceAll( "\\\\'", "" ) ); 438 if ( matcher.find() ) 439 { 440 comments[key + "." + matcher.group( 2 )] = commentWaiting; 441 commentWaiting = false; 442 continue; 443 } 342 444 343 /* 344 * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key. 345 * We're changing here the entry into the key. 346 * So 'Upload' becomes '#ckeditor_translation.Upload#' in our temporary template. 347 */ 348 matcher = regexLib.entry.matcher( line.replaceAll( "\\\\'", "" ) ); 349 if ( matcher.find() ) 350 { 351 out.push( matcher.group( 1 ) + matcher.group( 2 ) + matcher.group( 3 ) + "#" + key + "." + matcher.group( 2 ) + "#" 352 + matcher.group( 4 ) ); 353 continue; 354 } 355 356 /* 357 * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key. 358 * We're changing here the entry into the key. 359 * So ['AM', 'PM'] becomes 360 * ['#ckeditor_translation.DateAmPm[0]#', '#ckeditor_translation.DateAmPm[1]#'] 361 * in our temporary template. 362 */ 363 matcher = regexLib.arrayEntry.matcher( line.replaceAll( "\\\\'", "" ) ); 364 if ( matcher.find() ) 365 { 366 i = 0; 367 368 arrayEntryLine = matcher.group( 1 ) + matcher.group( 2 ) + matcher.group( 3 ); 369 arrayEntryKey = matcher.group( 2 ); 370 arrayEntryLineEnd = matcher.group( 5 ); 371 arrayEntryItems = matcher.group( 4 ); 372 373 arrayEntryItemsMatcher = regexLib.arrayItemEntry.matcher( arrayEntryItems ); 374 while ( arrayEntryItemsMatcher.find() ) 445 /* 446 * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key. 447 * We're changing here the entry into the key. 448 * So ['AM', 'PM'] becomes 449 * ['#ckeditor_translation.DateAmPm[0]#', '#ckeditor_translation.DateAmPm[1]#'] 450 * in our temporary template. 451 */ 452 matcher = regexLib.arrayEntry.matcher( line.replaceAll( "\\\\'", "" ) ); 453 if ( matcher.find() ) 375 454 { 376 matchResult = arrayEntryItemsMatcher.toMatchResult(); 377 if ( i > 0 ) 378 { 379 arrayEntryLine += ", "; 380 } 381 arrayEntryLine += "'#" + key + "." + arrayEntryKey + "[" + i + "]" + "#'"; 382 i++; 455 arrayEntryKey = matcher.group( 2 ); 456 comments[key + "." + arrayEntryKey] = commentWaiting; 457 commentWaiting = false; 458 continue; 383 459 } 384 arrayEntryLine += arrayEntryLineEnd;385 out.push( arrayEntryLine );386 continue;387 460 } 388 389 out.push( line );390 461 } 391 462 else 392 463 { 393 blockComment.push( line );464 blockComment.push( line.replace( '\t', '' ) ); 394 465 395 466 matcher = regexLib.blockCommentEnd.matcher( line ); 396 467 if ( matcher.find() ) 397 468 { 398 469 inBlockComment = false; 470 if ( commentWaiting !== false ) 471 comments['_'].push( commentWaiting ); 399 472 400 matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) ); 401 /** 402 * Add a placeholder for the fileOverview section. 403 */ 404 if ( matcher.find() ) 473 // Ignore Copyright comment. 474 matcher = regexLib.copyright.matcher( blockComment.join( "" ) ); 475 if ( !matcher.find() ) 405 476 { 406 out.push( "#ckeditor_translation.__fileOverview#" ); 477 matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) ); 478 if ( matcher.find() ) 479 comments['_'].push( "#ckeditor_translation.__fileOverview#" ); 480 else 481 commentWaiting = blockComment.join( CKLANGTOOL.EOL ); 407 482 } 408 else 409 { 410 out.push( blockComment.join( "\n" ) ); 411 } 483 412 484 blockComment = []; 413 485 } 414 486 } 415 487 } 416 488 417 /** 418 * Uncomment this line to see the template. 419 */ 420 // CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "template.txt" ), out.join( "\r\n" ), false ); 421 return out.join( "\n" ).replace(/\s*$/, "\n"); 489 return comments; 422 490 } 423 491 492 function outObject( o, key, comments, suffix ) 493 { 494 var i, objects = [], strings = [], out = [], line; 495 496 for( i in o ) 497 { 498 if ( typeof o[i] == 'string' ) 499 strings.push( i ); 500 else 501 objects.push( i ); 502 } 503 504 strings.sort(); 505 objects.sort(); 506 507 for ( i = 0 ; i < strings.length ; i++ ) 508 { 509 if ( comments[key + "." + strings[i]] ) 510 { 511 out.push( suffix + String( comments[key + "." + strings[i]] ).replace( /(?:\r\n|\r|\n)/g, CKLANGTOOL.EOL + suffix ) ); 512 } 513 514 if ( !/^(?:[a-zA-Z$_][\w$_]*)$/.test( strings[i] ) ) 515 line = suffix + outString( strings[i] ) + " : '#" + key + "." + strings[i] + "#'"; 516 else 517 line = suffix + strings[i] + " : '#" + key + "." + strings[i] + "#'"; 518 519 if ( objects.length || i != strings.length - 1 ) 520 line += ','; 521 522 if ( comments['_eol'][key + "." + strings[i]] ) 523 line += " " + comments['_eol'][key + "." + strings[i]]; 524 525 out.push( line ); 526 } 527 528 if (strings.length && objects.length) 529 out.push( "" ); 530 531 for ( i = 0 ; i < objects.length ; i++ ) 532 { 533 if ( i > 0 ) 534 out.push( "" ); 535 536 if ( comments[key + "." + objects[i]] ) 537 { 538 out.push( suffix + String( comments[key + "." + objects[i]] ).replace( /(?:\r\n|\r|\n)/g, CKLANGTOOL.EOL + suffix ) ); 539 } 540 541 line = suffix + objects[i] + ' :'; 542 543 if ( comments['_eol'][key + "." + objects[i]] ) 544 line += " " + comments['_eol'][key + "." + objects[i]]; 545 546 out.push( line ); 547 out.push( suffix + '{' ); 548 549 out.push( outObject( o[objects[i]], key + "." + objects[i], comments, suffix + '\t' ) ); 550 551 if ( i == objects.length -1 ) 552 out.push( suffix + '}' ); 553 else 554 out.push( suffix + '},' ); 555 } 556 557 return out.join( CKLANGTOOL.EOL ); 558 } 559 424 560 /** 425 561 * Return translation[translationKey]. 426 562 * … … 444 580 if ( translationKey == "__fileOverview" ) 445 581 return fileOverviewBlock; 446 582 447 while ( ( dotPos = translationKey.indexOf( "." )) != -1 )583 while ( ( dotPos = translationKey.indexOf( "." ) ) != -1 ) 448 584 { 449 result = result[ translationKey.substring( 0, dotPos )];450 if ( typeof ( result) == "undefined" )585 result = result[translationKey.substring( 0, dotPos )]; 586 if ( typeof ( result ) == "undefined" ) 451 587 { 452 588 return false; 453 589 } … … 460 596 var matcher = regexLib.arrayTranslationKey.matcher( translationKey ); 461 597 if ( matcher.find() ) 462 598 { 463 if ( typeof ( result[ matcher.group( 1 ) ]) != "object" )599 if ( typeof ( result[matcher.group( 1 )] ) != "object" ) 464 600 { 465 601 return false; 466 602 } 467 result = result[ matcher.group( 1 ) ][ matcher.group( 2 )];603 result = result[matcher.group( 1 )][matcher.group( 2 )]; 468 604 } 469 605 else 470 606 { 471 result = result[ translationKey];607 result = result[translationKey]; 472 608 } 473 609 474 if ( typeof ( result) == "undefined" )610 if ( typeof ( result ) == "undefined" ) 475 611 { 476 612 return false; 477 613 } … … 484 620 */ 485 621 function escapeString( string ) 486 622 { 487 return string.replace( /\\/g, "\\\\" ).replace( /\r/g, "\\r" ).replace( /\n/g, "\\n" ).replace( /'/g, "\\'" ).replace( /\u200b/g,488 "\\u200b" );623 return string.replace( /\\/g, "\\\\" ).replace( /\r/g, "\\r" ).replace( /\n/g, "\\n" ).replace( /'/g, "\\'" ).replace( 624 /\u200b/g, "\\u200b" ); 489 625 } 490 626 491 627 function processFile( file ) … … 512 648 /* 513 649 * common.textField[1] -> common.textField 514 650 */ 515 if ( replacement == false || missingKeys[ translationKey.replace( /\[\d+\]$/, "" )] )651 if ( replacement == false || missingKeys[translationKey.replace( /\[\d+\]$/, "" )] ) 516 652 { 517 653 /** 518 654 * FoldersTitle : '#ckeditor_translation.FoldersTitle#', -> 519 655 * FoldersTitle : '[MISSING_TRANSLATION]Folders', 520 656 */ 521 657 replacement = "[MISSING_TRANSLATION]" + getTranslation( CKLANGTOOL.englishTranslation, translationKey ); 522 string = ( string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ));658 string = ( string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ) ); 523 659 524 660 if ( translationKey.substring( 0, 2 ) != "__" ) 525 661 missing++; 526 662 } 527 663 else 528 664 { 529 string = ( string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ));665 string = ( string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ) ); 530 666 531 667 if ( translationKey.substring( 0, 2 ) != "__" ) 532 668 found++; … … 539 675 * Loop through all lines, remove [MISSING_TRANSLATION] and add 540 676 * //MISSING comment at the end of line (if necessary). 541 677 */ 542 var line, lines = string.split( "\n");678 var line, lines = string.split( CKLANGTOOL.EOL ); 543 679 for ( var i = 0 ; i < lines.length ; i++ ) 544 680 { 545 line = lines[ i];681 line = lines[i]; 546 682 if ( line.indexOf( "[MISSING_TRANSLATION]" ) != -1 ) 547 683 { 548 684 if ( line.indexOf( "//" ) == -1 ) 549 685 { 550 lines[ i] = line.replace( /\[MISSING_TRANSLATION\]/g, '' ) + " // MISSING";686 lines[i] = line.replace( /\[MISSING_TRANSLATION\]/g, '' ) + " // MISSING"; 551 687 } 552 688 else 553 689 { 554 lines[ i] = line.replace( "//", "// MISSING //" ).replace( /\[MISSING_TRANSLATION\]/g, '' );690 lines[i] = line.replace( "//", "// MISSING //" ).replace( /\[MISSING_TRANSLATION\]/g, '' ); 555 691 } 556 692 } 557 693 } 558 694 559 CKLANGTOOL.io.saveFile( file, lines.join( "\r\n" ), false );695 CKLANGTOOL.io.saveFile( file, lines.join( CKLANGTOOL.EOL ), true ); 560 696 561 697 var result = 562 698 { 563 found : found,564 missing : missing699 found : found, 700 missing : missing 565 701 }; 566 702 567 703 return result; … … 577 713 run : function() 578 714 { 579 715 CKLANGTOOL.template = createTemplate( CKLANGTOOL.templateFile ); 580 var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile ); 581 CKLANGTOOL.englishTranslation = result.translation; 716 var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile ); 717 CKLANGTOOL.englishTranslation = result.translation; 582 718 583 719 var children = CKLANGTOOL.languageDir.list(); 584 720 var errors, file, status = []; … … 586 722 587 723 for ( var i = 0 ; i < children.length ; i++ ) 588 724 { 589 if ( children[ i ] == 'en.js' )590 continue;591 592 725 /** 593 726 * Skip files beginning with underscore character. 594 727 */ 595 if ( children[ i ].charAt(0) == 95 )728 if ( children[i].charAt( 0 ) == 95 ) 596 729 continue; 597 598 if ( CKLANGTOOL.io.getExtension( children[ i] ) != "js" )730 731 if ( CKLANGTOOL.io.getExtension( children[i] ) != "js" ) 599 732 continue; 600 733 601 file = new File( CKLANGTOOL.languageDir, children[ i] );734 file = new File( CKLANGTOOL.languageDir, children[i] ); 602 735 if ( file.isFile() ) 603 736 { 604 737 print( "Processing " + file.getAbsolutePath() ); 605 738 result = processFile( file ); 606 739 checkFile( file ); 607 740 608 status.push( padRight( children[ i], 12 ) + "Found: " + result.found + " Missing: " + result.missing );741 status.push( padRight( children[i], 12 ) + "Found: " + result.found + " Missing: " + result.missing ); 609 742 foundFiles = true; 610 743 } 611 744 } … … 615 748 print( "WARNING: language files not found." ); 616 749 } 617 750 618 var header = "Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r\nFor licensing, see LICENSE.html or http://ckeditor.com/license\r\n\r\n"; 619 620 CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "_translationstatus.txt" ), header + status.join( "\r\n" ) + "\r\n", false ); 751 CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "_translationstatus.txt" ), CKLANGTOOL.header + CKLANGTOOL.EOL + CKLANGTOOL.EOL + status.join( CKLANGTOOL.EOL ), 752 true ); 621 753 print( "Process completed." ); 622 754 } 623 755 }; -
test/_assets/translator/_translationstatus.txt.correct.txt
1 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.1 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 2 2 For licensing, see LICENSE.html or http://ckeditor.com/license 3 3 4 de.js Found: 17 Missing: 4 5 pl.js Found: 18 Missing: 3 4 ar.js Found: 24 Missing: 1 5 de.js Found: 20 Missing: 5 6 en.js Found: 25 Missing: 0 7 pl.js Found: 22 Missing: 3 8 No newline at end of file -
test/_assets/translator/ar.js
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview Defines the {@link CKEDITOR.lang} object, for the 8 * Arabic language. 9 */ 10 11 /**#@+ 12 @type String 13 @example 14 */ 15 16 /** 17 * Constains the dictionary of language entries. 18 * @namespace 19 */ 20 CKEDITOR.lang['ar'] = 21 { 22 /** 23 * The language reading direction. Possible values are "rtl" for 24 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right 25 * languages (like English). 26 * @default 'ltr' 27 */ 28 dir : 'rtl', 29 30 // Toolbar buttons without dialogs. 31 source : 'المصدر', 32 newPage : 'صفحة جديدة', 33 save : 'حفظ', 34 preview : 'معاينة الصفحة', 35 36 // Common messages and labels. 37 common : 38 { 39 browseServer : 'تصفح', 40 url : 'الرابط', 41 protocol : 'البروتوكول', 42 confirmCancel : 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟', 43 }, 44 45 // Special char dialog. 46 specialChar : 47 { 48 toolbar : 'إدراج خاص.ِ', 49 title : 'اختر الخواص' 50 }, 51 52 // Link dialog. 53 link : 54 { 55 toolbar : 'رابط', 56 noAnchors : '(لا توجد علامات مرجعية في هذا المستند)', 57 noUrl : 'من فضلك أدخل عنوان الموقع الذي يشير إليه الرابط', 58 noEmail : 'من فضلك أدخل عنوان البريد الإلكتروني' 59 }, 60 61 // Table Dialog 62 table : 63 { 64 toolbar : 'جدول', 65 66 cell : 67 { 68 menu : 'خلية', 69 insertBefore : 'إدراج خلية قبل' 70 }, 71 72 row : 73 { 74 menu : 'صف' 75 } 76 }, 77 78 // Button Dialog. 79 button : 80 { 81 typeRst : 'إعادة تعيين' 82 }, 83 84 colors : 85 { 86 '000' : 'أسود', 87 '800000' : 'كستنائي', 88 'E6E6FA' : 'أرجواني', 89 'FFF' : 'أبيض' 90 } 91 }; -
test/_assets/translator/ar.js.correct.txt
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview Defines the {@link CKEDITOR.lang} object, for the 8 * Arabic language. 9 */ 10 11 /**#@+ 12 @type String 13 @example 14 */ 15 16 /** 17 * Constains the dictionary of language entries. 18 * @namespace 19 */ 20 CKEDITOR.lang['ar'] = 21 { 22 /** 23 * The language reading direction. Possible values are "rtl" for 24 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right 25 * languages (like English). 26 * @default 'ltr' 27 */ 28 dir : 'rtl', 29 /* 30 * Screenreader titles. Please note that screenreaders are not always capable 31 * of reading non-English words. So be careful while translating it. 32 */ 33 editorTitle : 'Rich text editor, %1', // MISSING 34 newPage : 'صفحة جديدة', 35 preview : 'معاينة الصفحة', 36 save : 'حفظ', 37 // Toolbar buttons without dialogs. 38 source : 'المصدر', 39 40 // Button Dialog. 41 button : 42 { 43 typeRst : 'إعادة تعيين' 44 }, 45 46 colors : 47 { 48 '000' : 'أسود', 49 '800000' : 'كستنائي', 50 E6E6FA : 'أرجواني', 51 FFF : 'أبيض' 52 }, 53 54 // Common messages and labels. 55 // Inline comment 56 // having more than one line. 57 common : 58 { 59 browseServer : 'تصفح', 60 confirmCancel : 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟', 61 protocol : 'البروتوكول', 62 url : 'الرابط' 63 }, 64 65 // Link dialog. 66 link : 67 { 68 noAnchors : '(لا توجد علامات مرجعية في هذا المستند)', 69 noEmail : 'من فضلك أدخل عنوان البريد الإلكتروني', 70 noUrl : 'من فضلك أدخل عنوان الموقع الذي يشير إليه الرابط', 71 toolbar : 'رابط' // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!! 72 }, 73 74 // Special char dialog. 75 specialChar : // Inline comment for special char dialog. 76 { 77 title : 'اختر الخواص', 78 toolbar : 'إدراج خاص.ِ' 79 }, 80 81 // Table Dialog 82 table : 83 { 84 toolbar : 'جدول', 85 86 cell : 87 { 88 insertBefore : 'إدراج خلية قبل', 89 menu : 'خلية' 90 }, 91 92 row : 93 { 94 menu : 'صف' 95 } 96 } 97 }; -
test/_assets/translator/de.js
51 51 // Link dialog. 52 52 link : 53 53 { 54 toolbar : 'Link einfügen/editieren',// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!54 toolbar : 'Link\u200b', // MISSING // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!! 55 55 noAnchors : '(keine Anker im Dokument vorhanden)', 56 56 noUrl : 'Bitte geben Sie die Link-URL an', 57 57 noEmail : 'Bitte geben Sie e-Mail Adresse an' … … 74 74 }, 75 75 }, 76 76 77 colors : 78 { 79 '000' : 'Schwarz', 80 '800000' : 'Kastanienbraun', 81 'E6E6FA' : 'Lavendel', 82 'FFF' : 'Weiß' 83 }, 84 77 85 // Button Dialog. 78 86 button : 79 87 { 80 88 typeRst : 'Zurücksetzen' 81 } ,89 } 82 90 }; 83 91 84 92 -
test/_assets/translator/de.js.correct.txt
26 26 * @default 'ltr' 27 27 */ 28 28 dir : 'ltr', 29 30 29 /* 31 30 * Screenreader titles. Please note that screenreaders are not always capable 32 31 * of reading non-English words. So be careful while translating it. 33 32 */ 34 editorTitle : 'Rich text editor, %1', // MISSING 35 33 editorTitle : 'Rich text editor, %1', // MISSING 34 newPage : 'Neue Seite', 35 preview : 'Vorschau', 36 save : 'Speichern', 36 37 // Toolbar buttons without dialogs. 37 source : 'Quellcode', 38 newPage : 'Neue Seite', 39 save : 'Speichern', 40 preview : 'Vorschau', 38 source : 'Quellcode', 41 39 42 // Common messages and labels.43 common :40 // Button Dialog. 41 button : 44 42 { 45 browseServer : 'Server durchsuchen', 46 url : 'Bildauswahl', 47 protocol : 'Protokoll', 48 confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING 43 typeRst : 'Zurücksetzen' 49 44 }, 50 45 51 // Special char dialog. 52 specialChar : 46 colors : 53 47 { 54 toolbar : 'Insert Special Character', // MISSING 55 title : 'Select Special Character' // MISSING 48 '000' : 'Schwarz', 49 '800000' : 'Kastanienbraun', 50 E6E6FA : 'Lavendel', 51 FFF : 'Weiß' 56 52 }, 57 53 54 // Common messages and labels. 55 // Inline comment 56 // having more than one line. 57 common : 58 { 59 browseServer : 'Server durchsuchen', 60 confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?', // MISSING 61 protocol : 'Protokoll', 62 url : 'Bildauswahl' 63 }, 64 58 65 // Link dialog. 59 66 link : 60 67 { 61 toolbar : 'Link einfügen/editieren', // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!62 no Anchors : '(keine Anker im Dokument vorhanden)',63 noUrl 64 noEmail : 'Bitte geben Sie e-Mail Adresse an'68 noAnchors : '(keine Anker im Dokument vorhanden)', 69 noEmail : 'Bitte geben Sie e-Mail Adresse an', 70 noUrl : 'Bitte geben Sie die Link-URL an', 71 toolbar : 'Link\u200b' // MISSING // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!! 65 72 }, 66 73 74 // Special char dialog. 75 specialChar : // Inline comment for special char dialog. 76 { 77 title : 'Select Special Character', // MISSING 78 toolbar : 'Insert Special Character' // MISSING 79 }, 80 67 81 // Table Dialog 68 82 table : 69 83 { 70 toolbar 84 toolbar : 'Tabelle', 71 85 72 86 cell : 73 87 { 74 menu : 'Zelle',75 insertBefore : 'Zelle davor einfügen',88 insertBefore : 'Zelle davor einfügen', 89 menu : 'Zelle' 76 90 }, 77 91 78 92 row : 79 93 { 80 menu : 'Zeile', 81 }, 82 }, 83 84 // Button Dialog. 85 button : 86 { 87 typeRst : 'Zurücksetzen' 88 }, 94 menu : 'Zeile' 95 } 96 } 89 97 }; -
test/_assets/translator/en.js
40 40 preview : 'Preview', 41 41 42 42 // Common messages and labels. 43 // Inline comment 44 // having more than one line. 43 45 common : 44 46 { 45 47 browseServer : 'Browser Server', … … 49 51 }, 50 52 51 53 // Special char dialog. 52 specialChar : 54 specialChar : // Inline comment for special char dialog. 53 55 { 54 56 toolbar : 'Insert Special Character', 55 57 title : 'Select Special Character' … … 81 83 }, 82 84 }, 83 85 86 colors : 87 { 88 '000' : 'Black', 89 '800000' : 'Maroon', 90 'E6E6FA' : 'Lavender', 91 'FFF' : 'White' 92 }, 93 84 94 // Button Dialog. 85 95 button : 86 96 { -
test/_assets/translator/en.js.correct.txt
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview Defines the {@link CKEDITOR.lang} object, for the English 8 * language. This is the base file for all translations. 9 */ 10 11 /**#@+ 12 @type String 13 @example 14 */ 15 16 /** 17 * Constains the dictionary of language entries. 18 * @namespace 19 */ 20 CKEDITOR.lang['en'] = 21 { 22 /** 23 * The language reading direction. Possible values are "rtl" for 24 * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right 25 * languages (like English). 26 * @default 'ltr' 27 */ 28 dir : 'ltr', 29 /* 30 * Screenreader titles. Please note that screenreaders are not always capable 31 * of reading non-English words. So be careful while translating it. 32 */ 33 editorTitle : 'Rich text editor, %1', 34 newPage : 'New Page', 35 preview : 'Preview', 36 save : 'Save', 37 // Toolbar buttons without dialogs. 38 source : 'Source', 39 40 // Button Dialog. 41 button : 42 { 43 typeRst : 'Reset' 44 }, 45 46 colors : 47 { 48 '000' : 'Black', 49 '800000' : 'Maroon', 50 E6E6FA : 'Lavender', 51 FFF : 'White' 52 }, 53 54 // Common messages and labels. 55 // Inline comment 56 // having more than one line. 57 common : 58 { 59 browseServer : 'Browser Server', 60 confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?', 61 protocol : 'Protocol', 62 url : 'URL' 63 }, 64 65 // Link dialog. 66 link : 67 { 68 noAnchors : '(No anchors available in the document)', 69 noEmail : 'Please type the e-mail address', 70 noUrl : 'Please type the link URL', 71 toolbar : 'Link\u200b' // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!! 72 }, 73 74 // Special char dialog. 75 specialChar : // Inline comment for special char dialog. 76 { 77 title : 'Select Special Character', 78 toolbar : 'Insert Special Character' 79 }, 80 81 // Table Dialog 82 table : 83 { 84 toolbar : 'Table', 85 86 cell : 87 { 88 insertBefore : 'Insert Cell Before', 89 menu : 'Cell' 90 }, 91 92 row : 93 { 94 menu : 'Row' 95 } 96 } 97 }; -
test/_assets/translator/pl.js
43 43 }, 44 44 45 45 // Special char dialog. 46 specialChar:46 'specialChar' : 47 47 { 48 48 toolbar : 'Wstaw znak specjalny', 49 title: 'Wybierz znak specjalny'49 'title' : 'Wybierz znak specjalny' 50 50 }, 51 51 52 52 // Link dialog. 53 53 link : 54 54 { 55 toolbar: 'Wstaw/edytuj hiperłącze', // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!55 'toolbar' : 'Wstaw/edytuj hiperłącze', // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!! 56 56 noAnchors : '(W dokumencie nie zdefiniowano żadnych etykiet)', 57 57 noUrl : 'Podaj adres URL', 58 58 noEmail : 'Podaj adres e-mail' … … 75 75 }, 76 76 }, 77 77 78 colors : 79 { 80 '000' : 'Czarny', 81 '800000' : 'Rdzawy', 82 'E6E6FA' : 'Lawendowy', 83 'FFF' : 'Biały' 84 }, 85 78 86 // Button Dialog. 79 87 button : 80 88 { -
test/_assets/translator/pl.js.correct.txt
26 26 * @default 'ltr' 27 27 */ 28 28 dir : 'ltr', 29 30 29 /* 31 30 * Screenreader titles. Please note that screenreaders are not always capable 32 31 * of reading non-English words. So be careful while translating it. 33 32 */ 34 editorTitle : 'Rich text editor, %1', // MISSING 35 33 editorTitle : 'Rich text editor, %1', // MISSING 34 newPage : 'Nowa strona', 35 preview : 'Podgląd', 36 save : 'Zapisz', 36 37 // Toolbar buttons without dialogs. 37 source : 'Źródło dokumentu', 38 newPage : 'Nowa strona', 39 save : 'Zapisz', 40 preview : 'Podgląd', 38 source : 'Źródło dokumentu', 41 39 42 // Common messages and labels.43 common :40 // Button Dialog. 41 button : 44 42 { 45 browseServer : 'Przeglądaj', 46 url : 'Adres URL', 47 protocol : 'Protokół', 48 confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING 43 typeRst : 'Wyzeruj' 49 44 }, 50 45 51 // Special char dialog. 52 specialChar : 46 colors : 53 47 { 54 toolbar : 'Wstaw znak specjalny', 55 title : 'Wybierz znak specjalny' 48 '000' : 'Czarny', 49 '800000' : 'Rdzawy', 50 E6E6FA : 'Lawendowy', 51 FFF : 'Biały' 56 52 }, 57 53 54 // Common messages and labels. 55 // Inline comment 56 // having more than one line. 57 common : 58 { 59 browseServer : 'Przeglądaj', 60 confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?', // MISSING 61 protocol : 'Protokół', 62 url : 'Adres URL' 63 }, 64 58 65 // Link dialog. 59 66 link : 60 67 { 61 toolbar : 'Wstaw/edytuj hiperłącze', // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!62 no Anchors : '(W dokumencie nie zdefiniowano żadnych etykiet)',63 noUrl 64 noEmail : 'Podaj adres e-mail'68 noAnchors : '(W dokumencie nie zdefiniowano żadnych etykiet)', 69 noEmail : 'Podaj adres e-mail', 70 noUrl : 'Podaj adres URL', 71 toolbar : 'Wstaw/edytuj hiperłącze' // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!! 65 72 }, 66 73 74 // Special char dialog. 75 specialChar : // Inline comment for special char dialog. 76 { 77 title : 'Wybierz znak specjalny', 78 toolbar : 'Wstaw znak specjalny' 79 }, 80 67 81 // Table Dialog 68 82 table : 69 83 { 70 toolbar 84 toolbar : 'Tabela', 71 85 72 86 cell : 73 87 { 74 menu : 'Komórka',75 insertBefore : 'Wstaw komórkę z lewej',88 insertBefore : 'Wstaw komórkę z lewej', 89 menu : 'Komórka' 76 90 }, 77 91 78 92 row : 79 93 { 80 menu : 'Row', // MISSING 81 }, 82 }, 83 84 // Button Dialog. 85 button : 86 { 87 typeRst : 'Wyzeruj' 88 }, 94 menu : 'Row' // MISSING 95 } 96 } 89 97 };