summaryrefslogtreecommitdiff
path: root/tools/localization/revcheck.php
diff options
context:
space:
mode:
Diffstat (limited to 'tools/localization/revcheck.php')
-rwxr-xr-xtools/localization/revcheck.php1159
1 files changed, 1159 insertions, 0 deletions
diff --git a/tools/localization/revcheck.php b/tools/localization/revcheck.php
new file mode 100755
index 000000000..0a0bc0cf6
--- /dev/null
+++ b/tools/localization/revcheck.php
@@ -0,0 +1,1159 @@
+#!/usr/bin/php -q
+<?php
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 4 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2011 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Thomas Sch�fbeck <tom@php.net> |
+ | Gabor Hojtsy <goba@php.net> |
+ | Mark Kronsbein <mk@php.net> |
+ | Jan Fabry <cheezy@php.net>
+ +----------------------------------------------------------------------+
+
+ $Id: revcheck.php 308406 2011-02-16 22:27:57Z yannick $
+*/
+if ($argc < 2 || $argc > 4) {
+?>
+
+Check the revision of translated files against
+the actual english xml files, and print statistics
+
+ Usage:
+ <?php echo $argv[0]; ?> <language-code> [<maintainer>] [--show-uptodate]
+
+ <language-code> must be a valid language code used
+ in the repository
+
+ If you specify <maintainer>, the script only checks
+ the files maintained by the person you add here
+
+ If you specify --show-uptodate option, the script will
+ also show uptodate files in the common file list
+
+ Read more about Revision comments and related
+ functionality in the PHP Documentation Howto:
+ http://php.net/dochowto
+
+<?php
+ exit;
+}
+
+// Long runtime
+set_time_limit(0);
+
+// A file is criticaly "outdated' if
+define("ALERT_REV", 10); // translation is 10 or more revisions behind the en_US one
+define("ALERT_SIZE", 3); // translation is 3 or more kB smaller than the en_US one
+define("ALERT_DATE", -30); // translation is 30 or more days older than the en_US one
+
+// Revision marks used to flag files
+define("REV_UPTODATE", 1); // actual file
+define("REV_NOREV", 2); // file with revision comment without revision
+define("REV_CRITICAL", 3); // criticaly old / small / outdated
+define("REV_OLD", 4); // outdated file
+define("REV_NOTAG", 5); // file without revision comment
+define("REV_NOTRANS", 6); // file without translation
+
+define("REV_CREDIT", 7); // only used in translators list
+define("REV_WIP", 8); // only used in translators list
+
+$gitOptions="--no-color -n 1";
+
+// Colors used to mark files by status (colors for the above types)
+$CSS = array(
+ REV_UPTODATE => "act",
+ REV_NOREV => "norev",
+ REV_CRITICAL => "crit",
+ REV_OLD => "old",
+ REV_NOTAG => "wip",
+ REV_NOTRANS => "wip",
+ REV_CREDIT => "wip",
+ REV_WIP => "wip",
+);
+
+function init_revisions() {
+ global $CSS;
+ return array_fill_keys(array_keys($CSS), 0);
+}
+
+function init_files_by_maint($persons) {
+ $result = array();
+ foreach($persons as $item) {
+ $result[$item['name']] = init_revisions();
+ }
+
+ return $result;
+}
+
+$file_sizes_by_mark = $files_by_mark = init_revisions();
+
+// Initializing variables from parameters
+$LANG = $argv[1];
+$MAINT = "";
+$SHOW_UPTODATE = FALSE;
+if ($argc == 3) {
+ if ($argv[2] == '--show-uptodate') {
+ $SHOW_UPTODATE = TRUE;
+ } else {
+ $MAINT = $argv[2];
+ }
+} elseif ($argc == 4) {
+ $MAINT = $argv[2];
+ $SHOW_UPTODATE = ($argv[3] == '--show-uptodate');
+}
+
+$DOCDIR=getenv("SCI")."/";
+chdir($DOCDIR);
+$DOCDIR=getcwd()."/";
+if (!is_dir($DOCDIR)) {
+ echo "Could not find $DOCDIR\n";
+ die();
+}
+// =========================================================================
+// Functions to get revision info and credits from a file
+// =========================================================================
+function get_last_commit_from_git($file) {
+ global $gitOptions;
+ $cmd="cd `dirname $file` > /dev/null; git log $gitOptions $file|head -1|cut -d' ' -f2; cd - > /dev/null";
+ $lastcommit=exec($cmd);
+ if (!$lastcommit) {
+ die("Error: Could not retrieve the last commit from git: ".$cmd);
+ }
+ return $lastcommit;
+}
+
+function get_last_revision_from_git($file) {
+ global $DOCDIR;
+ $commit=get_last_commit_from_git($file);
+ if (!$commit) {
+ die("Error: empty commit");
+ }
+ $tempFile="/tmp/git_rev-list.txt";
+ if (!is_file($tempFile)) {
+ exec("cd `dirname $DOCDIR` > /dev/null; git rev-list --reverse HEAD > $tempFile; cd - > /dev/null");
+ }
+ return exec("cd `dirname $file` > /dev/null; grep -n $commit $tempFile | cut -d: -f1; cd - > /dev/null");
+}
+
+function get_author_from_git($file) {
+ global $gitOptions;
+ return ucwords(strtolower(exec("cd `dirname $file` > /dev/null; git log $gitOptions $file|head -2|grep 'Author:'|sed -e 's|Author: \(.*\) <.*|\\1|g'; cd - > /dev/null")));
+
+}
+
+// Grabs the revision tag and stores credits from the file given
+function get_tags($file, $val = "en-rev") {
+
+ // Read the first 500 chars. The comment should be at
+ // the begining of the file
+ $fp = @fopen($file, "r") or die ("Unable to read $file.");
+ $line = fread($fp, 500);
+ fclose($fp);
+ // Return if this was needed (it should be there)
+ if ($val == "en-rev") {
+ return get_last_revision_from_git($file);
+// preg_match("/<!-- .Revision: (\d+) . -->/", $line, $match);
+// return $match[1];
+ }
+
+ // Handle credits (only if no maintainer is specified)
+ if ($val == "\\S*") {
+
+ global $files_by_maint;
+
+ // Find credits info, let more credits then one,
+ // using commas as list separator
+ if (preg_match("'<!--\s*CREDITS:\s*(.+)\s*-->'U", $line, $match_credit)) {
+ // Explode with commas a separators
+ $credits = explode(",", $match_credit[1]);
+
+ // Store all elements
+ foreach ($credits as $num => $credit) {
+ $files_by_maint[trim($credit)][REV_CREDIT]++;
+ }
+ }
+ }
+ global $LANG;
+ // No match before the preg
+ $match = array();
+ $match[0]="";
+ $match[1]=get_last_revision_from_git($file);//str_replace($LANG,"en_US",$file));
+ $match[2]=get_author_from_git($file);
+ $match[3]="";
+ return $match;
+ // Check for the translations "revision tag"
+ preg_match ("/<!--\s*EN-Revision:\s*(\d+)\s*Maintainer:\s*("
+ . $val . ")\s*Status:\s*(.+)\s*-->/U",
+ $line,
+ $match
+ );
+
+ // The tag with revision number is not found so search
+ // for n/a revision comment (comment where revision is not known)
+ if (count($match) == 0) {
+ preg_match ("'<!--\s*EN-Revision:\s*(n/a)\s*Maintainer:\s*("
+ . $val . ")\s*Status:\s*(.+)\s*-->'U",
+ $line,
+ $match
+ );
+ }
+
+ // Return with found revision info (number, maint, status)
+ return $match;
+
+} // get_tags() function end
+
+function detect_date_from_git($file) {
+ global $gitOptions;
+ $en_date=strtotime(trim(exec("cd `dirname $file` > /dev/null; git log $gitOptions --date=iso $file|grep Date:|sed -e \"s|Date:||g\"; cd - > /dev/null")));
+ return $en_date;
+}
+
+// =========================================================================
+// Functions to check file status in translated directory, and store info
+// =========================================================================
+
+// Checks a file, and gather status info
+function get_file_status($file) {
+
+ // The information is contained in these global arrays and vars
+ global $DOCDIR, $LANG, $MAINT, $SHOW_UPTODATE, $files_by_mark, $files_by_maint;
+ global $file_sizes_by_mark;
+ global $missing_files, $missing_tags, $using_rev;
+
+ // Transform english file name to translated file name
+ $trans_file = str_replace("en_US", $LANG, $file);
+ // If we cannot find the file, we push it into the missing files list
+ if (!@file_exists($trans_file)) {
+ $files_by_mark[REV_NOTRANS]++;
+ $trans_name = substr($trans_file, strlen($DOCDIR));
+
+ $size = intval(filesize($file)/1024);
+ $missing_files[substr($file, strlen($DOCDIR))] = array( $size );
+ $file_sizes_by_mark[REV_NOTRANS] += $size;
+
+ // compute en-tags just if they're needed in the WIP-Table
+ if($using_rev) {
+ $missing_files[$trans_name][] = get_tags($file);
+ }
+ return FALSE;
+ }
+
+ // No specific maintainer, check for a revision tag
+ if (empty($MAINT)) {
+ $trans_tag = get_tags($trans_file, "\\S*");
+ }
+ // If we need to check for a specific translator
+ else {
+ // Get translated files tag, with maintainer
+ $trans_tag = get_tags($trans_file, $MAINT);
+
+ // If this is a file belonging to another
+ // maintainer, than we would not like to
+ // deal with it anymore
+ if (count($trans_tag) == 0) {
+ $trans_tag = get_tags($trans_file, "\\S*");
+ // We found a tag for another maintainer
+ if (count($trans_tag) > 0) {
+ return FALSE;
+ }
+ }
+ }
+
+ // Compute sizes and diffs
+ $en_size = intval(filesize($file) / 1024);
+ $trans_size = intval(mb_strlen(file_get_contents($trans_file), 'UTF-8') / 1024);
+ $size_diff = intval($en_size) - intval($trans_size);
+
+ // If we found no revision tag, then collect this
+ // file in the missing tags list
+ if (count($trans_tag) == 0) {
+ $files_by_mark[REV_NOTAG]++;
+ $file_sizes_by_mark[REV_NOTAG] += $en_size;
+ $missing_tags[] = array(substr($trans_file, strlen($DOCDIR)), $en_size, $trans_size, $size_diff);
+ return FALSE;
+ }
+
+ // Distribute values in separate vars for further processing
+ list(, $this_rev, $this_maint, $this_status) = $trans_tag;
+
+ // Get English file revision
+ $en_rev = get_tags($file);
+
+ // If we have a numeric revision number (not n/a), compute rev. diff
+ if (is_numeric($this_rev)) {
+ $rev_diff = intval($en_rev) - intval($this_rev);
+ $trans_rev = $this_rev;
+ $en_rev = $en_rev;
+ $en_commit = get_last_commit_from_git($file);
+ $trans_commit = get_last_commit_from_git($trans_file);
+
+ } else {
+ // If we have no numeric revision, make all revision
+ // columns hold the rev from the translated file
+ $rev_diff = $trans_rev = $this_rev;
+ $en_rev = $en_rev;
+ }
+
+ // Compute times and diffs
+// $en_date = intval((time() - filemtime($file)) / 86400);
+ $en_date=detect_date_from_git($file);
+ if (!$en_date) {
+ die("Could not detect date");
+ }
+ $en_date = intval((time() - $en_date) / 86400);
+ $trans_date=detect_date_from_git($trans_file);
+
+ $trans_date = intval((time() - $trans_date) / 86400);
+ $date_diff = $en_date - $trans_date;
+
+ // If the file is up-to-date
+ if ($rev_diff === 0 && trim($this_status) === "ready") {
+ $status_mark = REV_UPTODATE;
+ } elseif ($en_rev < $this_rev && $date_diff > 0) {
+ $status_mark = REV_UPTODATE;
+ }
+ // Or make decision on file category by revision, date and size
+ elseif ($rev_diff >= ALERT_REV || $size_diff >= ALERT_SIZE || $date_diff <= ALERT_DATE) {
+ $status_mark = REV_CRITICAL;
+ } elseif ($rev_diff === "n/a") {
+ $status_mark = REV_NOREV;
+ } elseif ($rev_diff === 0) {
+ $status_mark = REV_WIP;
+ } else {
+ $status_mark = REV_OLD;
+ }
+
+ // Store files by status, and by maintainer too
+ $files_by_mark[$status_mark]++;
+ if (!isset($files_by_maint[$this_maint])) {
+ $files_by_maint[$this_maint]=Array();
+ }
+ if (!isset($files_by_maint[$this_maint][$status_mark])) {
+ $files_by_maint[$this_maint][$status_mark]=Array();
+ }
+
+ $files_by_maint[$this_maint][$status_mark]++;
+ $file_sizes_by_mark[$status_mark] += $en_size;
+
+ if (REV_UPTODATE === $status_mark && !$SHOW_UPTODATE) {
+ return FALSE;
+ }
+
+ return array(
+ "full_name" => $file,
+ "short_name" => basename($trans_file),
+ "revision" => array($en_rev, $trans_rev, $rev_diff),
+ "commit" => array($en_commit, $trans_commit),
+ "size" => array($en_size, $trans_size, $size_diff),
+ "date" => array($en_date, $trans_date, $date_diff),
+ "maintainer" => $this_maint,
+ "status" => $this_status,
+ "mark" => $status_mark
+ );
+
+} // get_file_status() function end
+
+// =========================================================================
+// A function to check directory status in translated directory
+// =========================================================================
+
+// Check the status of files in a diretory of phpdoc XML files
+// The English directory is passed to this function to check
+function get_dir_status($dir,$lang) {
+
+ global $DOCDIR;
+
+ // Collect files and diretcories in these arrays
+ $directories = array();
+ $files = array();
+
+ // Open the directory
+ $handle = @opendir($dir);
+
+ // Walk through all names in the directory
+ while ($file = @readdir($handle)) {
+
+ if (
+ (!is_dir($dir.'/' .$file) && !in_array(substr($file, -3), array('xml','ent')) && substr($file, -13) != 'PHPEditBackup' )
+ || strpos($file, 'entities.') === 0
+ || $dir == $DOCDIR.'en/chmonly/' || $dir == $DOCDIR.'en/internals/' || $dir == $DOCDIR.'en/internals2/'
+ || $file == 'contributors.ent' || $file == 'contributors.xml'
+ || ($dir == $DOCDIR.'en/appendices/' && ($file == 'reserved.constants.xml' || $file == 'extensions.xml'))
+ || $file == 'README'
+ || $file == 'DO_NOT_TRANSLATE'
+ || $file == 'rsusi.txt'
+ || $file == 'missing-ids.xml'
+ || $file == 'license.xml'
+ || $file == 'master_help.xml'
+ || preg_grep("/scilab_.*_help/",Array($dir))
+ || $file == 'versions.xml'
+ ) {
+ continue;
+ }
+
+ if ($file != '.' && $file != '..' && $dir != '/functions') {
+ if (is_dir($dir.'/' .$file)) {
+ $directories[] = $file;
+ } elseif (is_file($dir.'/' .$file)) {
+ if (strpos($dir,"help/$lang")) {
+ $files[] = $file;
+ }
+ }
+ }
+
+ }
+
+ // Close the directory
+ @closedir($handle);
+
+ // Sort files and directories
+ sort($directories);
+ sort($files);
+
+ // Go through files first
+ $dir_status = array();
+ foreach ($files as $file) {
+ // If the file status is OK, append the status info
+ if ($file_status = get_file_status($dir.$file)) {
+ $dir_status[] = $file_status;
+ }
+ }
+
+ // Then go through subdirectories, merging all the info
+ // coming from subdirs to one array
+ foreach ($directories as $file) {
+// if (sizeof($dir_status) < 1) {
+// echo $dir.$file;
+ $dir_status = array_merge(
+ $dir_status,
+ get_dir_status($dir.$file.'/',$lang)
+ );
+// }
+ }
+
+ // Return with collected file info in
+ // this dir and subdirectories [if any]
+ return $dir_status;
+
+} // get_dir_status() function end
+
+
+// Check for files removed in the EN tree, but still living in the translation
+function get_old_files($dir) {
+
+ global $DOCDIR, $LANG;
+
+ // Collect files and diretcories in these arrays
+ $directories = array();
+ $files = array();
+
+ $special_files = array(
+ // french
+ 'LISEZ_MOI.txt',
+ 'TRADUCTIONS.txt',
+ 'Translators',
+ 'translation.xml'
+ // todo: add all missing languages
+ );
+
+ // Open the directory
+ $handle = @opendir($dir);
+
+ // Walk through all names in the directory
+ while ($file = @readdir($handle)) {
+
+ // If we found a file with one or two point as a name,
+ // a SVN directory, or an editor backup file skip the file
+ if (preg_match("/^\.{1,2}/", $file)
+ || substr($file, -1) == '~' // Emacs backup file
+ || substr($file, -4) == '.new'
+ ) {
+ continue;
+ }
+ // skip this files
+ if (in_array($file, $special_files)) {
+ continue;
+ }
+
+ // Collect files and directories
+ if (is_dir($dir.$file)) {
+ $directories[] = $file;
+ } else {
+ $files[] = $file;
+ }
+ }
+
+ // Close the directory
+ @closedir($handle);
+
+ // Sort files and directories
+ sort($directories);
+ sort($files);
+
+ // Go through files first
+ $old_files_status = array();
+ foreach ($files as $file) {
+
+ $en_dir = preg_replace("'^".$DOCDIR.$LANG."/'", $DOCDIR."en/", $dir);
+
+ if (!@file_exists($en_dir.$file) ) {
+ $old_files_status[$dir.$file] = array(0=>intval(filesize($dir.$file)/1024));
+ }
+
+ }
+
+ // Then go through subdirectories, merging all the info
+ // coming from subdirs to one array
+ foreach ($directories as $file) {
+ $old_files_status = array_merge(
+ $old_files_status,
+ get_old_files($dir.$file.'/')
+ );
+ }
+
+ return $old_files_status;
+
+} // get_old_files() function end
+
+
+// =========================================================================
+// Functions to read in the translation.xml file and process contents
+// =========================================================================
+
+// Get a multidimensional array with tag attributes
+function parse_attr_string ($tags_attrs) {
+
+ $tag_attrs_processed = array();
+
+ // Go through the tag attributes
+ foreach($tags_attrs as $attrib_list) {
+
+ // Get attr name and values
+ preg_match_all("!(.+)=\\s*([\"'])\\s*(.+)\\2!U", $attrib_list, $attribs);
+
+ // Assign all attributes to one associative array
+ $attrib_array = array();
+ foreach ($attribs[1] as $num => $attrname) {
+ $attrib_array[trim($attrname)] = trim($attribs[3][$num]);
+ }
+
+ // Collect in order of tags received
+ $tag_attrs_processed[] = $attrib_array;
+
+ }
+
+ // Retrun with collected attributes
+ return $tag_attrs_processed;
+
+} // parse_attr_string() end
+
+// Parse the translation.xml file for
+// translation related meta information
+function parse_translation($DOCDIR, $LANG, $MAINT) {
+
+ global $files_by_mark;
+
+ // Path to find translation.xml file, set default values,
+ // in case we can't find the translation file
+ $translation_xml = "tools/localization/translation-$LANG.xml";
+ $output_charset = 'iso-8859-1';
+ $translation = array(
+ "intro" => "",
+ "persons" => array(),
+ "files" => array(),
+ "allfiles" => array(),
+ );
+
+ // Check for file availability, return with default
+ // values, if we cannot find the file
+ if (!@file_exists($translation_xml)) {
+ return array($output_charset, $translation);
+ }
+
+ // Else go on, and load in the file, replacing all
+ // space type chars with one space
+ $txml = join("", file($translation_xml));
+ $txml = preg_replace("/\\s+/", " ", $txml);
+
+ // Get intro text (different for a persons info and
+ // for a whole group info page)
+ if (empty($MAINT)) {
+ preg_match("!<intro>(.+)</intro>!s", $txml, $match);
+ $translation["intro"] = trim($match[1]);
+ } else {
+ $translation["intro"] = "Personal Statistics for ".$MAINT;
+ }
+
+ // Get encoding for the output, from the translation.xml
+ // file encoding (should be the same as the used encoding
+ // in HTML)
+ preg_match("!<\?xml(.+)\?>!U", $txml, $match);
+ $xmlinfo = parse_attr_string($match);
+ $output_charset = $xmlinfo[1]["encoding"];
+
+ // Get persons list preg pattern, only check for a specific
+ // maintainer, if the users asked for it
+ if (empty($MAINT)) {
+ $pattern = "!<person(.+)/\\s?>!U";
+ } else {
+ $pattern = "!<person([^<]+nick=\"".$MAINT."\".+)/\\s?>!U";
+ }
+
+ // Find all persons matching the pattern
+ preg_match_all($pattern, $txml, $matches);
+ $translation['persons'] = parse_attr_string($matches[1]);
+
+ // Get list of work in progress files
+ if (empty($MAINT)) {
+
+ // Get all wip files
+ preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches);
+ $translation['files'] = parse_attr_string($matches[1]);
+
+ // Provide info about number of WIP files
+ $files_by_mark[REV_WIP] += count($translation['files']);
+
+ } else {
+
+ // Only check for a specific maintainer, if we were asked to
+ preg_match_all("!<file([^<]+person=\"".$MAINT."\".+)/\\s?>!U", $txml, $matches);
+ $translation['files'] = parse_attr_string($matches[1]);
+
+ // Other maintainers wip files need to be cleared from
+ // available files list in the future, so store that info too.
+ preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches);
+ $translation['allfiles'] = parse_attr_string($matches[1]);
+
+ // Provide info about number of WIP files
+ $files_by_mark[REV_WIP] += count($translation['allfiles']);
+
+ }
+
+ // Return with collected info in two vars
+ return array($output_charset, $translation);
+
+} // parse_translation() function end()
+
+// =========================================================================
+// Start of the program execution
+// =========================================================================
+
+// Check for directory validity
+if (!@is_dir($DOCDIR . $LANG)) {
+// die("The $LANG language code is not valid");
+}
+
+// Parse translation.xml file for more information
+list($charset, $translation) = parse_translation($DOCDIR, $LANG, $MAINT);
+
+// Add WIP files to maintainers file count and figure out,
+// if we need to use optional date and revision columns
+$using_date = FALSE; $using_rev = FALSE;
+$files_by_maint = init_files_by_maint($translation['persons']);
+foreach ($translation["files"] as $num => $fileinfo) {
+ $files_by_maint[$fileinfo["person"]][REV_WIP]++;
+ if (isset($fileinfo["date"])) { $using_date = TRUE; }
+ if (isset($fileinfo["revision"])) { $using_rev = TRUE; }
+}
+
+// Get all files status
+//$files_status = get_dir_status($DOCDIR."/modules/core/","en_US");//."en/");
+$files_status = get_dir_status($DOCDIR,"en_US");//."en/");
+
+// Get all old files in <lang> directory
+$old_files = get_old_files($DOCDIR.$LANG."/");
+
+$navbar = "<p class=c><a href=\"#intro\">Introduction</a> | " .
+ "<a href=\"#translators\">Translators</a> | " .
+ "<a href=\"#filesummary\">File summary by type</a> | " .
+ "<a href=\"#files\">Files</a> | ";
+
+if ( count($translation["files"]) != 0 ) {
+ $navbar .= "<a href=\"#wip\">Work in progress</a> | ";
+}
+
+$navbar .= "<a href=\"#missfiles\">Untranslated files</a> | " .
+ "<a href=\"#oldfiles\">Old files</a></p>\n";
+
+
+// Figure out generation date
+$date = date("r");
+
+// =========================================================================
+// Start of HTML page
+// =========================================================================
+
+print <<<END_OF_MULTILINE
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html>
+<head>
+<title>Scilab documentation Revision-check</title>
+<meta http-equiv="Content-Type" content="text/html; charset={$charset}">
+<style type="text/css">
+<!--
+h2,td,a,p,a.ref,th { font-family:Arial,Helvetica,sans-serif; font-size:14px; }
+h2,th,a.ref { color:#FFFFFF; }
+td,a,p { color:#000000; }
+h2 { font-size:28px; }
+th { font-weight:bold; }
+.blue { background-color:#666699; }
+.act { background-color:#68D888; }
+.norev { background-color:#f4a460; }
+.old { background-color:#eee8aa; }
+.crit { background-color:#ff6347; }
+.wip { background-color:#dcdcdc; }
+.r { text-align:right }
+.rb { text-align:right; font-weight:bold; }
+.c { text-align:center }
+body { margin:0px 0px 0px 0px; background-color:#F0F0F0; }
+//-->
+</style>
+</head>
+<body>
+<table width="100%" border="0" cellspacing="0" bgcolor="#666699">
+<tr><td>
+<table width="100%" border="0" cellspacing="1" bgcolor="#9999CC">
+<tr><td><h2 class=c>Status of the translated Scilab Manual</h2><p class=c style="font-size:12px;">Generated: {$date} &nbsp; / &nbsp; Language: $LANG<br></p></td></tr>
+</table>
+</td></tr>
+</table>
+END_OF_MULTILINE;
+
+print ($navbar);
+
+// =========================================================================
+// Intro block goes here
+// =========================================================================
+
+// If we have an introduction text, print it out, with an anchor
+if (!empty($translation["intro"])) {
+ echo '<a name="intro"></a>';
+ echo '<table width="800" align="center"><tr><td class=c>' .
+ $translation['intro'] . '</td></tr></table>';
+}
+
+// =========================================================================
+// Files summary table goes here
+// =========================================================================
+
+// Do not print out file summary table, if we are printing out a page
+// for only one maintainer (his personal summary is in the table above)
+if (empty($MAINT)) {
+
+print <<<END_OF_MULTILINE
+<a name="filesummary"></a>
+<table width="450" border="0" cellpadding="4" cellspacing="1" align="center">
+<tr class=blue>
+<th>File status type</th>
+<th>Number of files</th>
+<th>Percent of files</th>
+<th>Size of files (kB)</th>
+<th>Percent of size</th>
+</tr>
+END_OF_MULTILINE;
+
+ $files_sum = array_sum($files_by_mark);
+ $file_sizes_sum = array_sum($file_sizes_by_mark);
+
+ $file_types = array(
+ array (REV_UPTODATE, "Up to date files"),
+ array (REV_OLD, "Old files"),
+ array (REV_CRITICAL, "Critical files"),
+ array (REV_WIP, "Work in progress"),
+// array (REV_NOREV, "Files without revision number"),
+// array (REV_NOTAG, "Files without revision tag"),
+ array (REV_NOTRANS, "Files available for translation")
+ );
+
+ foreach ($file_types as $num => $type) {
+ echo "<tr class=".$CSS[$type[0]].">".
+ "<td>".$type[1]."</td>".
+ "<td class=c>".intval($files_by_mark[$type[0]])."</td>".
+ "<td class=c>".number_format($files_by_mark[$type[0]] * 100 / $files_sum, 2 ).
+ "%</td>".
+ "<td class=c>".intval($file_sizes_by_mark[$type[0]])."</td>".
+ "<td class=c>".number_format($file_sizes_by_mark[$type[0]] * 100 / $file_sizes_sum, 2).
+ "%</td></tr>\n";
+ }
+
+ echo "<tr class=blue><th>Files total</th><th>$files_sum</th><th>100%</th><th>$file_sizes_sum</th><th>100%</th></tr>\n".
+ "</table>\n<p>&nbsp;</p>\n";
+
+}
+
+echo $navbar."<p>&nbsp;</p>\n";
+
+// =========================================================================
+// Files table goes here
+// =========================================================================
+
+if (count($files_status) != 0) {
+
+print <<<END_OF_MULTILINE
+<a name="files"></a>
+<table width="820" border="0" cellpadding="4" cellspacing="1" align="center">
+<tr class=blue>
+<th rowspan=2>Translated file</th>
+<th colspan=2>Revision</th>
+<th colspan=3>Size in kB</th>
+<th colspan=3>Age in days</th>
+<th rowspan=2>Maintainer</th>
+<th rowspan=2>Status</th>
+</tr>
+<tr class=blue>
+<th>en_US</th>
+<th>$LANG</th>
+<th>en_US</th>
+<th>$LANG</th>
+<th>diff</th>
+<th>en_US</th>
+<th>$LANG</th>
+<th>diff</th>
+</tr>
+END_OF_MULTILINE;
+
+ // This was the previous directory [first]
+ $prev_dir = false;
+
+ // Go through all files collected
+ foreach ($files_status as $num => $file) {
+// print_r($file);
+// die();
+ // Make the maintainer a link, if we have that maintainer in the list
+ if (isset($maint_by_nick[$file["maintainer"]])) {
+ $file["maintainer"] = '<a href="#maint' . $maint_by_nick[$file["maintainer"]] .
+ '">' . $file["maintainer"] . '</a>';
+ }
+
+ // If we have a 'numeric' revision diff and it is not zero,
+ // make a link to the git repository's diff script
+ if ($file["revision"][2] != "n/a" && $file["revision"][2] !== 0) {
+ $url="http://cgit.scilab.org/scilab/diff/?id="
+ .$file['commit'][0]."d2=".$file['commit'][1];
+ $file['short_name'] = '<a href="' . $url . '">'. $file["short_name"] . '</a> ';
+// '<a href="' . $url_ws . '">[NoWS]</a>';--
+ }
+
+ // Guess the new directory from the full name of the file
+ $new_dir = dirname($file["full_name"]);
+
+ // If this is a new directory, put out old dir lines
+ if ($new_dir !== $prev_dir) {
+ if (isset($lines)) {
+ echo $prev_diplay_dir;
+ echo " ($line_number)</th></tr>";
+ echo $lines;
+ }
+
+ $lines = '';
+ $line_number = 0;
+
+ // Store the new actual directory
+ $prev_dir = $new_dir;
+ }
+ // Drop out the unneeded parts from the dirname, special case for root dir...
+ $display_dir = str_replace(array($DOCDIR), array("", '/'), dirname($file["full_name"]));
+ $prev_diplay_dir = "<tr class=blue><th colspan=12>$display_dir";
+
+ // Save the line for the current file (get file name shorter)
+ $lines .= "<tr class={$CSS[$file['mark']]}><td>{$file['short_name']}</td>".
+ "<td> {$file['revision'][0]}</td>" .
+ "<td> {$file['revision'][1]}</td>".
+ "<td class=r>{$file['size'][0]} </td>".
+ "<td class=r>{$file['size'][1]} </td>".
+ "<td class=rb>{$file['size'][2]} </td>".
+ "<td class=r>{$file['date'][0]} </td>".
+ "<td class=r>{$file['date'][1]} </td>".
+ "<td class=rb>{$file['date'][2]} </td>".
+ "<td class=c>{$file['maintainer']}</td>".
+ "<td class=c>".trim($file['status'])."</td></tr>\n";
+ $line_number++;
+
+ }
+
+ // echo the last dir and $lines
+ echo "$prev_diplay_dir ($line_number)</th></tr>";
+ echo $lines;
+
+ echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
+
+}
+
+
+// =========================================================================
+// Translators table goes here
+// =========================================================================
+
+// If person list available (valid translation.xml file in lang), print out
+// the person list, with respect to the maintainer parameter specified
+if (!empty($translation["persons"])) {
+
+print <<<END_OF_MULTILINE
+<a name="translators"></a>
+<table width="820" border="0" cellpadding="4" cellspacing="1" align="center">
+<tr class=blue>
+<th rowspan=2>Translator's name</th>
+<th rowspan=2>Contact email</th>
+<th colspan=7>Files maintained</th>
+</tr>
+<tr>
+<th class="{$CSS[REV_CREDIT]}" style="color:#000000">cre-<br>dits</th>
+<th class="{$CSS[REV_UPTODATE]}" style="color:#000000">upto-<br>date</th>
+<th class="{$CSS[REV_OLD]}" style="color:#000000">old</th>
+<th class="{$CSS[REV_CRITICAL]}" style="color:#000000">cri-<br>tical</th>
+<th class="{$CSS[REV_NOREV]}" style="color:#000000">no<br>rev</th>
+<th class="{$CSS[REV_WIP]}" style="color:#000000">wip</th>
+<th class="blue">sum</th>
+</tr>
+END_OF_MULTILINE;
+
+ // ' Please leave this comment here
+
+ // We will collect the maintainers by nick here
+ $maint_by_nick = array();
+
+ // Print out a line for each maintainer (with respect to
+ // maintainer setting provided in command line)
+ foreach($translation["persons"] as $num => $person) {
+
+ // Do not print out this person, if a
+ // specific maintainer info is asked for
+ if (!empty($MAINT) && $person["name"] != $MAINT) {
+ continue;
+ }
+
+ // Put maintaner number into associative array
+ // [Used in further tables for referencing]
+ $maint_by_nick[$person["name"]] = $num;
+
+ // Decide on the SVN text and the color of the line
+ if (isset($person["vcs"]) && $person["vcs"] === "yes") {
+ $svnu = "x";
+ $col = "old";
+ } else {
+ $svnu = "&nbsp;";
+ $col = "wip";
+ }
+
+ // Try to do some antispam actions
+ $person["email"] = str_replace(
+ "@",
+ "<small>:at:</small>",
+ $person["email"]
+ );
+
+ // Get file info for this person
+ if (isset($files_by_maint[$person["name"]])) {
+ $pi = $files_by_maint[$person["name"]];
+ } else {
+ $pi = array();
+ }
+
+ echo "<tr class=$col>" .
+ "<td><a name=\"maint$num\">$person[name]</a></td>" .
+ "<td>$person[email]</td>" .
+ "<td class=c>" . $pi[REV_CREDIT] . "</td>" .
+ "<td class=c>" . $pi[REV_UPTODATE] . "</td>" .
+ "<td class=c>" . $pi[REV_OLD] . "</td>" .
+ "<td class=c>" . $pi[REV_CRITICAL] . "</td>" .
+ "<td class=c>" . $pi[REV_NOREV] . "</td>" .
+ "<td class=c>" . $pi[REV_WIP] . "</td>" .
+ "<th class=blue>" . array_sum($pi) . "</th>" .
+ "</tr>\n";
+ }
+
+ echo "</table>\n<p>&nbsp;</p>\n";
+}
+
+// =========================================================================
+// Work in progress table goes here
+// =========================================================================
+
+// If work-in-progress list is available (valid translation.xml file in lang)
+if (count($translation["files"]) != 0) {
+
+ // Print out files table header
+ echo "<a name=\"wip\"></a>\n" .
+ "<table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\">\n" .
+ "<tr class=blue>".
+ "<th>Work in progress files</th>".
+ "<th>Translator</th>".
+ "<th>Type</th>";
+
+ // Print out date and revision columns if needed
+ if ($using_date) {
+ echo '<th>Date</th>';
+ }
+ if ($using_rev) {
+ echo '<th>CO-Revision</th>' .
+ '<th>EN-Revision</th>';
+ }
+ echo "</tr>\n";
+
+ // Go through files, and print out lines for them
+ foreach($translation["files"] as $num => $finfo) {
+
+ // If we have a valid maintainer, link to the summary
+ if (isset($maint_by_nick[$finfo["person"]])) {
+ $finfo["person"] = '<a href="#maint' . $maint_by_nick[$finfo["person"]] .
+ '">' . $finfo["person"] . '</a>';
+ }
+
+ // Print out the line with the first columns
+ echo "<tr class=wip><td>$finfo[name]</td>" .
+ "<td>$finfo[person]</td><td>$finfo[type]</td>";
+
+ // If we need the date column, print it out
+ if ($using_date) {
+ echo "<td>$finfo[date]</td>";
+ }
+
+ // If we need the revision column, print it out
+ if ($using_rev) {
+ echo "<td>$finfo[revision]</td><td>" .
+ $missing_files[$finfo["name"]][1] .
+ "</td>";
+ }
+
+ // End the line
+ echo "</tr>\n";
+
+ // Collect files in WIP list
+ $wip_files[$finfo["name"]] = TRUE;
+ }
+
+ echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
+
+}
+
+// Files translated, but without a revision comment
+$count = count($missing_tags);
+
+if ($count > 0) {
+ echo "<a name=\"misstags\"></a>" .
+ "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n".
+ "<tr class=blue><th rowspan=2>Files without Revision-comment ($count files):</th>".
+ "<th colspan=3>Sizes in kB</th></tr>\n".
+ "<tr class=blue><th>en_US</th><th>$LANG</th><th>diff</th></tr>\n";
+
+ foreach($missing_tags as $val) {
+
+ // Shorten the filename (we have directory headers)
+ $short_file = basename($val[0]);
+
+ // Guess the new directory from the full name of the file
+ $new_dir = dirname($val[0]);
+
+ // If this is a new directory, put out dir headline
+ if ($new_dir != $prev_dir) {
+
+ // Print out directory header
+ echo "<tr class=blue><th colspan=4>$new_dir</th></tr>\n";
+
+ // Store the new actual directory
+ $prev_dir = $new_dir;
+ }
+ echo "<tr class=wip><td>$short_file</td><td class=r>$val[1]</td>".
+ "<td class=r>$val[2]</td><td class=r>$val[3]</td></tr>\n";
+ }
+
+ echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
+}
+
+// Merge all work in progress files collected
+$wip_files = array_merge(
+ $translation["files"], // Files for this translator
+ $translation["allfiles"] // Files for all the translators
+);
+
+// Delete wip entires from available files list
+foreach ($wip_files as $file) {
+ if (isset($missing_files[$file['name']])) {
+ unset($missing_files[$file['name']]);
+ }
+}
+
+// Files not translated and not "wip"
+$count = count($missing_files);
+if ($count > 0) {
+
+ echo "<a name=\"missfiles\"></a>" .
+ "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n" .
+ "<tr class=blue><th><a name=\"avail\" class=\"ref\">" .
+ " Available for translation</a> ($count files):</th><th>kB</th></tr>\n";
+
+ foreach($missing_files as $file => $info) {
+ // Shorten the filename (we have directory headers)
+ $short_file = basename($file);
+
+ // Guess the new directory from the full name of the file
+ $new_dir = dirname($file);
+
+ // If this is a new directory, put out dir headline
+ if ($new_dir != $prev_dir) {
+
+ // Print out directory header if not "."
+ echo "<tr class=blue><th colspan=2>$new_dir</th></tr>\n";
+
+ // Store the new actual directory
+ $prev_dir = $new_dir;
+ }
+
+ echo "<tr class=wip><td><a href=\"http://cgit.scilab.org/scilab/tree/scilab/$file\">$short_file</a></td>" .
+ "<td class=r>$info[0]</td></tr>\n";
+ }
+ echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
+
+}
+
+// Files not in EN tree
+$count = count($old_files);
+
+if ($count > 0) {
+
+ print "<a name=\"oldfiles\"></a>" .
+ "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n" .
+ "<tr class=blue><th><a name=\"notEn\" class=\"ref\">" .
+ " Not in EN Tree</a> ($count files):</th><th>kB</th></tr>\n";
+
+ foreach($old_files as $file => $info) {
+
+ // Shorten the filename (we have directory headers)
+ $short_file = basename($file);
+
+ // Guess the new directory from the full name of the file
+ $new_dir = dirname($file);
+
+ // If this is a new directory, put out dir headline
+ if ($new_dir != $prev_dir) {
+
+ // Print out directory header if not "."
+ echo "<tr class=blue><th colspan=2>$new_dir</th></tr>\n";
+
+ // Store the new actual directory
+ $prev_dir = $new_dir;
+ }
+
+ echo "<tr class=wip><td>$short_file</td>" .
+ "<td class=r>$info[0]</td></tr>\n";
+ }
+ echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
+
+}
+
+
+// All OK, end the file
+echo "</body>\n</html>\n";
+
+?>