goba Sat Mar 23 17:44:03 2002 EDT
Modified files:
/phpdoc/scripts revcheck.php
Log:
Renewed revcheck code, separated logic from presentation [mostly],
added color types, revision types, colors to translators table, a new
file summary table, removed green files, etc...
Please test, there may be some problems under the hood, though it seems
OK for the hu translation without maintainer restrictions...
Index: phpdoc/scripts/revcheck.php
diff -u phpdoc/scripts/revcheck.php:1.18 phpdoc/scripts/revcheck.php:1.19
--- phpdoc/scripts/revcheck.php:1.18 Fri Mar 22 18:30:33 2002
+++ phpdoc/scripts/revcheck.php Sat Mar 23 17:44:02 2002
@@ -34,14 +34,6 @@
If you specify <maintainer>, the script only checks
the files maintaned by the person you add here
- Revision comment syntax for translated files:
-
- <!-- EN-Revision: 1.34 Maintainer: tom Status: ready -->
-
- If the revision number is not (yet) known:
-
- <!-- EN-Revision: n/a Maintainer: tom Status: working -->
-
Read more about Revision comments and related
funcionality in the PHP Documentation Howto.
@@ -53,206 +45,365 @@
exit;
}
- // CONFIG SECTION
- $docdir = "../"; // Main directory of the PHP documentation (one dir up in cvs)
+// 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 one
+define("ALERT_SIZE", 10); // translation is 10 or more kB smaller than the en one
+define("ALERT_DATE", -30); // translation is 30 or more days older than the en one
+
+// Revision marks used to flag files
+define("REV_ACTUAL", 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
+
+define("NORMHEAD", 9); // only used in table outputs (css)
+
+// Colors used to mark files by status (colors for the above types)
+$CSS = array(
+ REV_ACTUAL => "background-color: #68D888; color: #000000;",
+ REV_NOREV => "background-color: #f4a460; color: #000000;",
+ REV_CRITICAL => "background-color: #ff6347; color: #000000;", #ff0000
+ REV_OLD => "background-color: #eee8aa; color: #000000;",
+ REV_NOTAG => "background-color: #dcdcdc; color: #000000;",
+ REV_NOTRANS => "background-color: #dcdcdc; color: #000000;",
+ REV_CREDIT => "background-color: #dcdcdc; color: #000000;",
+ REV_WIP => "background-color: #dcdcdc; color: #000000;",
+ NORMHEAD => "background-color: #666699; color: #ffffff;",
+);
+
+// Option for the link to cvs.php.net: normal: "&f=h"
+// long diff: "&f=h&num=10", unified (text): "&f=u"
+define("CVS_OPT", "&f=h&num=10");
+
+// Initializing variables from parameters
+$LANG = $argv[1];
+if ($argc == 3) {
+ $MAINT = $argv[2];
+} else {
+ $MAINT = "";
+}
- // Warn with red color if
- $r_alert = 10; // the translation is $r_alert or more revisions behind the en one
- $s_alert = 10; // the translation is $s_alert or more kB smaller than the en one
- $t_alert = 30; // the translation is $t_alert or more days older than the en one
-
- // Option for the link to the cvs.php.net: normal: "&f=h"
- // long diff: "&f=h&num=10", unified (text): "&f=u"
- $cvs_opt = "&f=h&num=10";
-
- /*********************************************************************/
- /* Nothing to modify below this line */
- /*********************************************************************/
-
- // Long runtime
- set_time_limit(0);
-
- // Initializing arrays and vars
- $missed_files = array();
- $miss_tag = array();
- $t_alert = -1 * $t_alert;
- $lang = $argv[1];
- if ($argc == 3) { $maintainer = $argv[2]; }
- else { $maintainer = ""; }
+// Main directory of the PHP documentation (one dir up
+// in cvs). We do need the trailing slash!
+$DOCDIR = "../";
- /*********************************************************************/
- /* Here starts the functions part */
- /*********************************************************************/
-
- // Grabs the revision tag from the file given
- function get_tag($file, $val = "en-rev")
- {
+// =========================================================================
+// Functions to get revision info and credits from a file
+// =========================================================================
+
+// Grabs the revision tag from the file given
+function get_tag($file, $val = "en-rev")
+{
- // Read the first 200 chars, the comment should be at
+ // Read the first 200 chars. The comment should be at
// the begining of the file
$fp = @fopen($file, "r") or die ("Unable to read $file.");
$line = fread($fp, 200);
fclose($fp);
- // Checking for english CVS revision tag
- if ($val=="en-rev") {
- preg_match("/<!-- .Revision: \d+\.(\d+) . -->/", $line, $match);
- return ($match[1]);
- }
- // Checking for the translations "revision tag"
- else {
- preg_match ("/<!--\s*EN-Revision:\s*\d+\.(\d+)\s*Maintainer:\s*(".$val.
- ")\s*Status:\s*(.+)\s*-->/", $line, $match);
+ // Check for English CVS revision tag (. is for $ in the preg!),
+ // Return if this was needed (it should be there)
+ if ($val == "en-rev") {
+ preg_match("/<!-- .Revision: \d+\.(\d+) . -->/", $line, $match);
+ return $match[1];
}
+
+ // No match before the preg
+ $match = array();
+
+ // Check for the translations "revision tag"
+ preg_match ("/<!--\s*EN-Revision:\s*\d+\.(\d+)\s*Maintainer:\s*("
+ . $val . ")\s*Status:\s*(.+)\s*-->/",
+ $line,
+ $match
+ );
+
// The tag with revision number is not found so search
- // for n/a revision comment
+ // 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*-->'", $line, $match);
+ preg_match ("'<!--\s*EN-Revision:\s*(n/a)\s*Maintainer:\s*("
+ . $val . ")\s*Status:\s*(.+)\s*-->'",
+ $line,
+ $match
+ );
}
- return ($match);
- } // get_tag() function end
-
- // Grab CREDITS tag, the place to store previous credits
- function get_credits ($file) {
+
+ // Return with found revision info (number, maint, status)
+ return $match;
+
+} // get_tag() function end
+
+// Grab CREDITS tag, the place to store previous credits
+function get_credits ($file) {
// Read the first 300 chars, the comment should be at
- // the begining of the file
+ // the begining of the file, if it is there
$fp = @fopen($file, "r") or die ("Unable to read $file.");
$line = fread($fp, 300);
fclose($fp);
+ // Try to find credits info in file, let more credits
+ // then one, using commas as list separator
if (preg_match("'<!--\s*CREDITS:\s*(.+)\s*-->'U",
- $line, $match)) {
- return (explode(",", $match[1]));
+ $line,
+ $match)) {
+
+ // Explode with commas a separators
+ $credits = explode(",", $match[1]);
+
+ // Trim all elements (let spaces to be
+ // between credit info)
+ foreach ($credits as $num => $credit) {
+ $credits[$num] = trim($credit);
+ }
+
+ return $credits;
+
} else {
+
+ // No credits info in this file
return array();
}
- } // get_credits() end
- // Checks a file, and gather stats
- function check_file($file, $file_cnt)
- {
+} // get_credits() end
+
+// =========================================================================
+// Functions to check file status in translated directory, and store info
+// =========================================================================
+
+// Collect or return missing files depending on
+// the parameters passed to this function
+function missing_file()
+{
+ // Static var to store info, and return if asked
+ static $missing_files = array();
+ global $DOCDIR, $LANG;
+
+ // Return with the missing files,
+ // in case of no parameters to this function
+ if (func_num_args() == 0) {
+ return $missing_files;
+ }
+
+ // Get the parameters if we have them
+ list($en_file, $trans_file) = func_get_args();
+
+ // Compute new index for missing file (name without language dir)
+ $index = substr($trans_file, strlen($DOCDIR) + strlen($LANG) + 1);
+
+ // Compute new valie for missing file (size and EN revision)
+ $value = array(
+ round(filesize($en_file)/1024, 1),
+ "1." . get_tag($en_file)
+ );
+
+ // Push file into array
+ $missing_files[$index] = $value;
+
+} // missing_file() function end
+
+// Collect or return files with missing tags depending on
+// the parameters passed to this function
+function missing_tag()
+{
+ // Static var to store info, and return if asked
+ static $missing_tags = array();
+ global $DOCDIR;
+
+ // Return with the file with missing tags,
+ // in case of no parameters to this function
+ if (func_num_args() == 0) {
+ return $missing_tags;
+ }
+
+ // Get the parameter if we have it
+ list($trans_file) = func_get_args();
+
+ // Push file name with missing tag on the list
+ $missing_tags[] = substr($trans_file, strlen($DOCDIR));
+}
+
+// Collect files by status mark
+function files_by_mark()
+{
+ // Static var to store info, and return if asked
+ static $files_by_mark = array();
+
+ // Return with the file with missing tags,
+ // in case of no parameters to this function
+ if (func_num_args() == 0) {
+ return $files_by_mark;
+ }
+
+ // Get the parameter if we have it
+ list($mark, $inc) = func_get_args();
+
+ // Add one to the count of this type of files
+ $files_by_mark[$mark] += $inc;
+
+}
+
+// Collect files by maintainer and status mark
+function files_by_maint()
+{
+ // Static var to store info, and return if asked
+ static $files_by_maint = array();
+
+ // Return with the file with missing tags,
+ // in case of no parameters to this function
+ if (func_num_args() == 0) {
+ return $files_by_maint;
+ }
+
+ // Get the parameter if we have it
+ list($mark, $maint) = func_get_args();
+
+ // Add one to the maintainers files list,
+ // especially counting this type of file
+ $files_by_maint[$maint][$mark]++;
+
+}
+
+// Checks a file, and gather status info
+function get_file_status($file)
+{
// The information is contained in these global arrays and vars
- global $missed_files, $miss_tag, $lang, $docdir, $r_alert,
- $s_alert, $t_alert, $maintainer, $cvs_opt, $plist,
- $personinfo;
-
- // Translated file name check
- $t_file = preg_replace( "'^".$docdir."en/'", $docdir.$lang."/", $file );
- if (!file_exists($t_file)) {
- $missed_files[substr($t_file, strlen($docdir)+strlen($lang)+1)] =
- array(round(filesize($file)/1024, 1), get_tag($file));
- return FALSE;
- }
-
- // Get translated files tag, with maintainer if needed
- if (!empty($maintainer)) {
- $t_tag = get_tag($t_file, $maintainer);
- // Don't count other's Tags as missing
- if (count($t_tag) == 0) {
- $t_tag = get_tag($t_file, "\\S*");
- if (count($t_tag) > 0)
- return FALSE;
- }
+ global $DOCDIR, $LANG, $MAINT;
+
+ // Transform english file name to translated file nme
+ $trans_file = preg_replace("'^{$DOCDIR}en/'", "{$DOCDIR}{$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, 1);
+ missing_file($file, $trans_file);
+ return FALSE;
+ }
+
+ // If we need to check for a specific translator
+ if (!empty($MAINT)) {
+ // Get translated files tag, with maintainer
+ $trans_tag = get_tag($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_tag($trans_file, "\\S*");
+ // We found a tag for another maintainer
+ if (count($trans_tag) > 0) {
+ return FALSE;
+ }
+ }
+ }
+ // No specific maintainer, check for a revision tag
+ else {
+ $trans_tag = get_tag($trans_file, "\\S*");
}
- else
- $t_tag = get_tag($t_file, "\\S*");
- // No tag found
- if (count($t_tag) == 0) {
- $miss_tag[] = substr($t_file, strlen($docdir));
- return FALSE;
- }
-
- // Storing values for further processing
- $maint = $t_tag[2];
- $en_rev = get_tag($file);
-
- // Make the maintainer a link
- if (isset($plist[$maint])) {
- $maintd = '<a href="#maint' . $plist[$maint] . '">' . $maint . '</a>';
- } else {
- $maintd = $maint;
+ // 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, 1);
+ missing_tag($trans_file, $DOCDIR);
+ return FALSE;
+ }
+
+ // Distribute values in separate vars for further processing
+ list(, $this_rev, $this_maint, $this_status) = $trans_tag;
+ $this_credits = get_credits($trans_file);
+
+ // Add credits to file by maintainer list
+ foreach ($this_credits as $nick) {
+ files_by_maint(REV_CREDIT, $nick);
}
+
+ // Get translated file name (without directories)
+ $trans_name = substr($trans_file, strlen($DOCDIR) + strlen($LANG) + 1);
- // Get credits comment, and add to array
- $credits = get_credits($t_file);
- foreach ($credits as $nick) {
- $personinfo[trim($nick)]["credits"]++;
- }
-
- // Make diff link if the revision is not n/a
- $t_td = substr($t_file, strlen($docdir)+strlen($lang)+1);
- if (is_numeric($t_tag[1])) {
- $r_diff = intval($en_rev) - intval($t_tag[1]);
- $t_rev = "1.".$t_tag[1];
- if ($r_diff != 0) {
- $t_td = "<a href=\"http://cvs.php.net/diff.php/".
- preg_replace( "'^".$docdir."'", "phpdoc/", $file ).
- "?r1=1.$t_tag[1]&r2=1.$en_rev$cvs_opt\">$t_td</a>";
- }
+ // Get English file revision for revision computing
+ $en_rev = get_tag($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 = "1.{$this_rev}";
+ $en_rev = "1.{$en_rev}";
} else {
- $r_diff = $t_rev = $t_tag[1];
+ // If we have no numeric revision, make all revision
+ // columns hold the rev from the translated file
+ $rev_diff = $trans_rev = $this_rev;
}
// Compute sizes, times and diffs
- $en_size = intval(filesize($file) / 1024);
- $t_size = intval(filesize($t_file) / 1024);
- $s_diff = intval($en_size) - intval($t_size);
- $en_date = intval((time() - filemtime($file)) / 86400);
- $t_date = intval((time() - filemtime($t_file)) / 86400);
- $t_diff = $en_date - $t_date;
-
- // Taging actuality of files with colors
- if ($r_diff === 0) {
- $col = "\"#68D888\"";
- $personinfo[$maint]["actual"]++;
- } elseif ($r_diff == "n/a") {
- $col = "\"#f4a460\" class=\"hl\"";
- $personinfo[$maint]["norev"]++;
- } elseif ($r_diff >= $r_alert || $s_diff >= $s_alert || $t_diff <= $t_alert) {
- $col = "\"#ff0000\" class=\"hl\"";
- $personinfo[$maint]["veryold"]++;
+ $en_size = intval(filesize($file) / 1024);
+ $trans_size = intval(filesize($trans_file) / 1024);
+ $size_diff = intval($en_size) - intval($trans_size);
+
+ $en_date = intval((time() - filemtime($file)) / 86400);
+ $trans_date = intval((time() - filemtime($trans_file)) / 86400);
+ $date_diff = $en_date - $trans_date;
+
+ // Make decision on file category by revision, date and size
+ if ($rev_diff === 0) {
+ $status_mark = REV_ACTUAL;
+ } elseif ($rev_diff === "n/a") {
+ $status_mark = REV_NOREV;
+ } elseif ($rev_diff >= ALERT_REV || $size_diff >= ALERT_SIZE || $date_diff <=
+ALERT_DATE) {
+ $status_mark = REV_CRITICAL;
} else {
- $col ="\"#eee8aa\"";
- $personinfo[$maint]["old"]++;
+ $status_mark = REV_OLD;
}
+
+ // Store files by status, and by maintainer too
+ files_by_mark ($status_mark, 1);
+ files_by_maint($status_mark, $this_maint);
+
+ return array(
+ "full_name" => $file,
+ "short_name" => $trans_name,
+ "revision" => array($en_rev, $trans_rev, $rev_diff),
+ "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
+ );
+
- // Write out directory headline
- if ($file_cnt == 0) {
- $display_dir = preg_replace("'($docdir)(.+)/[^/]*$'", "\\2/", $t_file);
- print("<tr><th colspan=\"12\" height=\"3\"
bgcolor=\"#666699\">$display_dir</th></tr>");
- }
-
- // Write out the line for the file into the file
- print("<tr>\n <td bgcolor=$col>$t_td</td>\n".
- " <td bgcolor=$col> 1.$en_rev</td><td bgcolor=$col> $t_rev</td>\n".
- " <td bgcolor=$col align=\"right\"><b>$r_diff</b> </td>\n".
- " <td bgcolor=$col align=\"right\">$en_size </td>\n".
- " <td bgcolor=$col align=\"right\">$t_size </td>\n".
- " <td bgcolor=$col align=\"right\"><b>$s_diff</b> </td>\n".
- " <td bgcolor=$col align=\"right\">$en_date </td>\n".
- " <td bgcolor=$col align=\"right\">$t_date </td>\n".
- " <td bgcolor=$col align=\"right\"><b>$t_diff</b> </td>\n".
- " <td bgcolor=$col align=\"center\">$maintd </td>\n".
- " <td bgcolor=$col align=\"center\">$t_tag[3] </td>\n</tr>\n");
return TRUE;
- } // check_file() end
+} // 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, $DOCDIR, $LANG)
+{
- // Checks a diretory of phpdoc XML files
- function check_dir($dir)
- {
- global $docdir, $lang;
-
// Collect files and diretcories in these arrays
$directories = array();
- $files = array();
+ $files = array();
- // Open and traverse the directory
+ // 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,
+ // or a CVS directory, skip the file
if (preg_match("/^\.{1,2}/",$file) || $file == 'CVS')
continue;
@@ -261,283 +412,591 @@
else { $files[] = $file; }
}
+
+ // Close the directory
@closedir($handle);
// Sort files and directories
sort($directories);
sort($files);
- // Files first...
- $file_cnt = 0;
+ // Go through files first
+ $dir_status = array();
foreach ($files as $file) {
- if (check_file($dir.$file, $file_cnt)) { $file_cnt++; }
+ // If the file status is OK, append the status info
+ if ($file_status = get_file_status("{$dir}{$file}")) {
+ $dir_status[] = $file_status;
+ }
}
- // than the subdirs
+ // Then go through subdirectories, merging all the info
+ // coming from subdirs to one array
foreach ($directories as $file) {
- check_dir($dir.$file."/");
+ $dir_status = array_merge(
+ $dir_status,
+ get_dir_status("{$dir}{$file}/", $DOCDIR, $LANG)
+ );
}
- } // check_dir() end
-
- // Get a multidimensional array with tag attributes
- function get_attr_array ($tags_attrs)
- {
+
+ // Return with collected file info in
+ // this dir and subdirectories [if any]
+ return $dir_status;
+
+} // get_dir_status() 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;
- } // get_attr_array() end
-
- // Print preformatted (debug function)
- function print_pre($var)
- {
- print("<pre>");
- print_r($var);
- print("</pre>");
- } // print_pre() end
- /*********************************************************************/
- /* Here starts the program */
- /*********************************************************************/
-
- // Check for directory validity
- if (!@is_dir($docdir . $lang)) {
- die("The $lang language code is not valid");
- }
-
- // Used regexps here for parsing to be compatible with
- // non XML compatible PHP setups
- $translation_xml = $docdir . $lang . "/translation.xml";
- $output_charset = 'iso-8859-1';
- $translation = array();
- if (@file_exists($translation_xml)) {
+} // parse_attr_string() end
+
+// Parse the translation.xml file for
+// translation related meta information
+function parse_translation($DOCDIR, $LANG, $MAINT)
+{
+ // Path to find translation.xml file, set default values,
+ // in case we can't find the translation file
+ $translation_xml = "{$DOCDIR}{$LANG}/translation.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
- if (!empty($maintainer))
- $translation["intro"] = "Personal Statistics for ".$maintainer;
- else {
+ // Get intro text (different for a persons info and
+ // for a whole group info page)
+ if (!empty($MAINT)) {
+ $translation["intro"] = "Personal Statistics for {$MAINT}";
+ } else {
preg_match("!<intro>(.+)</intro>!s", $txml, $match);
$translation["intro"] = trim($match[1]);
}
- // Get encoding for the output
+ // 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 = get_attr_array($match);
+ $xmlinfo = parse_attr_string($match);
$output_charset = $xmlinfo[1]["encoding"];
- // Get persons list
- if (!empty($maintainer))
- $pattern = "!<person([^<]+nick=\"$maintainer\".+)/\\s?>!U";
- else
+ // Get persons list preg pattern, only check for a specific
+ // maintainer, if the users asked for it
+ if (!empty($MAINT)) {
+ $pattern = "!<person([^<]+nick=\"{$MAINT}\".+)/\\s?>!U";
+ } else {
$pattern = "!<person(.+)/\\s?>!U";
+ }
+
+ // Find all persons matching the pattern
preg_match_all($pattern, $txml, $matches);
- $translation['persons'] = get_attr_array($matches[1]);
- foreach($translation['persons'] as $num => $person) {
- $plist[$person["nick"]] = $num;
- }
- $personinfo = array();
-
- // Get files list
- if (!empty($maintainer)) {
- preg_match_all("!<file([^<]+person=\"$maintainer\".+)/\\s?>!U", $txml,
$matches);
- $translation['files'] = get_attr_array($matches[1]);
- // get all others to clear out from available files
+ $translation['persons'] = parse_attr_string($matches[1]);
+
+ // Get list of work in progress files
+ if (!empty($MAINT)) {
+
+ // 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);
- $wip_others = get_attr_array($matches[1]);
- }
- else {
+ $translation['allfiles'] = parse_attr_string($matches[1]);
+
+ // Provide info about number of WIP files
+ files_by_mark(REV_WIP, count($translation['allfiles']));
+
+ } else {
+
+ // Get all wip files
preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches);
- $translation['files'] = get_attr_array($matches[1]);
+ $translation['files'] = parse_attr_string($matches[1]);
+
+ // Provide info about number of WIP files
+ files_by_mark(REV_WIP, count($translation['files']));
+
}
- }
+
+ // Return with collected info in two vars
+ return array($output_charset, $translation);
+
+} // parse_translation() function end()
+
+// =========================================================================
+// Debug functions for all the functions and code on this page
+// =========================================================================
+
+// Print preformatted (debug function)
+function print_pre($var)
+{
+ print("<pre>");
+ print_r($var);
+ print("</pre>");
+} // print_pre() 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);
- print("
-<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">
+// Add WIP files to maintainers file count
+foreach ($translation["files"] as $num => $fileinfo) {
+ files_by_maint(REV_WIP, $fileinfo["person"]);
+}
+
+// Get all files status
+$files_status = get_dir_status("{$DOCDIR}en/", $DOCDIR, $LANG);
+
+// Get missing files and files with missing
+// tags collected in the previous step
+$missing_files = missing_file();
+$missing_tags = missing_tag();
+
+// Files counted by mark and maintainer
+$files_by_mark = files_by_mark();
+$files_by_maint = files_by_maint();
+
+// 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>PHPDOC Revision-check</title>
-<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$output_charset\">
-<style type=\"text/css\"><!--
- h2 {font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 28px; }
- td,a,p {font-family: Arial,Helvetica,sans-serif; color: #000000; font-size: 14px; }
- a.ref {font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 14px; }
- th {font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 14px;
font-weight: bold; }
-.hl {font-family: Arial,Helvetica,sans-serif; color: #000000; font-size: 14px;
font-weight: bold; }
-body {margin-left: 0px; margin-right: 0px; margin-top: 0px; margin-bottom: 0px; }
+<meta http-equiv="Content-Type" content="text/html; charset={$charset}">
+<style type="text/css">
+<!--
+ h2, td, a, p, a.ref, th, .hl {
+ font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 14px;
+ }
+ h2 { font-size: 28px; }
+ td,a,p, th.black { color: #000000; }
+ th { font-weight: bold; }
+ .hl { color: #000000; font-weight: bold; }
+ body { margin: 0px 0px 0px 0px; }
//-->
</style>
</head>
-<body bgcolor=\"#F0F0F0\">
-<table width=\"100%\" border=\"0\" cellspacing=\"0\" bgcolor=\"#666699\">
+<body bgcolor="#F0F0F0">
+<table width="100%" border="0" cellspacing="0" bgcolor="#666699">
<tr><td>
- <table width=\"100%\" border=\"0\" cellspacing=\"1\" bgcolor=\"#9999CC\">
- <tr><td><h2 align=\"center\">Status of the translated PHP Manual</h2>
- <p align=\"center\" style=\"font-size:12px; color:#FFFFFF;\">Generated:
".date("r").
- " / Language: $lang<br> </p>
+ <table width="100%" border="0" cellspacing="1" bgcolor="#9999CC">
+ <tr><td><h2 align="center">Status of the translated PHP Manual</h2>
+ <p align="center" style="font-size:12px;">
+ Generated: {$date} / Language: $LANG<br></p>
</td></tr>
</table>
</td></tr>
-</table> <br>");
-
-if (isset($translation["intro"])) {
+</table>
+<p align="center"><a href="#intro">Introduction</a> |
+<a href="#translators">Translators</a> |
+<a href="#filesummary">File summary by type</a> |
+<a href="#files">Files</a> |
+<a href="#wip">Work in progress</a> |
+<a href="#misstags">Missing revision numbers</a> |
+<a href="#missfiles">Untranslated files</a>
+</p>
+END_OF_MULTILINE;
+
+// =========================================================================
+// Intro block goes here
+// =========================================================================
+
+// If we have an introduction text, print it out, with an anchor
+if (!empty($translation["intro"])) {
+ print('<a name="intro"></a>');
print('<table width="800" align="center"><tr><td>' . $translation['intro'] .
'</td></tr></table><p></p>');
}
-ob_start();
+// =========================================================================
+// 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>
+ <th rowspan="2" bgcolor="#666699">Translator's name</th>
+ <th rowspan="2" bgcolor="#666699">Contact email</th>
+ <th rowspan="2" bgcolor="#666699">Nick</th>
+ <th rowspan="2" bgcolor="#666699">CVS</th>
+ <th colspan="7" bgcolor="#666699">Files maintained</th>
+</tr>
+<tr>
+ <th style="{$CSS[REV_CREDIT]}">credits</th>
+ <th style="{$CSS[REV_ACTUAL]}">actual</th>
+ <th style="{$CSS[REV_OLD]}">old</th>
+ <th style="{$CSS[REV_CRITICAL]}">critical</th>
+ <th style="{$CSS[REV_NOREV]}">norev</th>
+ <th style="{$CSS[REV_WIP]}">wip</th>
+ <th style="{$CSS[NORMHEAD]}">sum</th>
+</tr>
+END_OF_MULTILINE;
+
+ // ' Please leave this comment here
-print("
-<table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\"
align=\"center\">
+ // 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["nick"] != $MAINT) {
+ continue;
+ }
+
+ // Put maintaner number into associative array
+ // [Used in further tables for referencing]
+ $maint_by_nick[$person["nick"]] = $num;
+
+ // Decide on the CVS text and the color of the line
+ if ($person["cvs"] === "yes") {
+ $cvsu = "x";
+ $col = '"#eee8aa"';
+ } else {
+ $cvsu = " ";
+ $col = '"#dcdcdc"';
+ }
+
+ // 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["nick"]])) {
+ $pi = $files_by_maint[$person["nick"]];
+ } else {
+ $pi = array();
+ }
+
+ print("<tr bgcolor=$col>" .
+ "<td><a name=\"maint$num\">$person[name]</a></td>" .
+ "<td>$person[email] </td>" .
+ "<td>$person[nick] </td>" .
+ "<td align=\"center\">$cvsu </td>" .
+ "<td align=\"center\">" . $pi[REV_CREDIT] . " </td>" .
+ "<td align=\"center\">" . $pi[REV_ACTUAL] . " </td>" .
+ "<td align=\"center\">" . $pi[REV_OLD] . " </td>" .
+ "<td align=\"center\">" . $pi[REV_CRITICAL] . " </td>" .
+ "<td align=\"center\">" . $pi[REV_NOREV] . " </td>" .
+ "<td align=\"center\">" . $pi[REV_WIP] . " </td>" .
+ "<td align=\"center\">" . array_sum($pi) . " </td>" .
+ "</tr>\n");
+ }
+
+ print "</table>\n<p> </p>\n";
+}
+
+// =========================================================================
+// Files summary table goes here
+// =========================================================================
+
+print <<<END_OF_MULTILINE
+<a name="filesummary"></a>
+<table width="450" border="0" cellpadding="4" cellspacing="1" align="center">
<tr>
- <th rowspan=\"2\" bgcolor=\"#666699\"><a name=\"translated\"
class=\"ref\">Translated file</a></th>
- <th colspan=\"3\" bgcolor=\"#666699\">Revision</th>
- <th colspan=\"3\" bgcolor=\"#666699\">Size in kB</th>
- <th colspan=\"3\" bgcolor=\"#666699\">Age in days</th>
- <th rowspan=\"2\" bgcolor=\"#666699\">Maintainer</th>
- <th rowspan=\"2\" bgcolor=\"#666699\">Status</th>
+ <th bgcolor="#666699">File status type</th>
+ <th bgcolor="#666699">Number of files</th>
+ <th bgcolor="#666699">Percent of files</th>
</tr>
+END_OF_MULTILINE;
+
+$files_sum = array_sum($files_by_mark);
+
+$file_types = array(
+ array (REV_ACTUAL, "Actual 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) {
+ $type[] = 'style="' . $CSS[$type[0]] . '"';
+ $type[] = intval($files_by_mark[$type[0]]);
+ $type[] = number_format(
+ $files_by_mark[$type[0]] * 100 / $files_sum, 2
+ );
+
+print <<<END_OF_MULTILINE
<tr>
- <th bgcolor=\"#666699\">en</th>
- <th bgcolor=\"#666699\">$lang</th>
- <th bgcolor=\"#666699\">diff</th>
- <th bgcolor=\"#666699\">en</th>
- <th bgcolor=\"#666699\">$lang</th>
- <th bgcolor=\"#666699\">diff</th>
- <th bgcolor=\"#666699\">en</th>
- <th bgcolor=\"#666699\">$lang</th>
- <th bgcolor=\"#666699\">diff</th>
+ <td {$type[2]}>{$type[1]}</td>
+ <td {$type[2]} align="center">{$type[3]}</td>
+ <td {$type[2]} align="center">{$type[4]}%</td>
</tr>
-");
+END_OF_MULTILINE;
+
+}
-// Check the English directory
-check_dir($docdir."en/");
+//print_pre($files_by_mark);
print("</table>\n<p> </p>\n");
-// If work-in-progress available (valid translation.xml file in lang)
-if (isset($translation["files"])) {
- $using_date = FALSE; $using_rev = FALSE;
- foreach ($translation["files"] as $file) {
- if (isset($file["date"])) { $using_date = TRUE; }
- if (isset($file["revision"])) { $using_rev = TRUE; }
- }
- print("
- <table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\"
align=\"center\">
- <tr>
- <th bgcolor=\"#666699\"><a name=\"wip\" class=\"ref\">Work in progress
files</a></th>
- <th bgcolor=\"#666699\">Translator</th>
- <th bgcolor=\"#666699\">Type</th>
- ");
- if ($using_date) { print ("<th bgcolor=\"#666699\">Date</th>\n"); }
- if ($using_rev) { print ("<th bgcolor=\"#666699\">CO-Revision</th><th
bgcolor=\"#666699\">EN-Revision</th>\n"); }
- print("</tr>\n");
-
- foreach($translation["files"] as $num => $finfo) {
- if (isset($plist[$finfo["person"]])) {
- $maintd = '<a href="#maint' . $plist[$finfo["person"]] . '">' .
$finfo["person"] . '</a>';
- } else {
- $maintd = $finfo["person"];
- }
- print("<tr bgcolor=\"#DDDDDD\"><td>$finfo[name]</td>" .
- "<td>$maintd</td><td>$finfo[type]</td>");
- if ($using_date) { print("<td>$finfo[date]</td>"); }
- if ($using_rev) { print("<td>$finfo[revision]</td><td>1." .
$missed_files[$finfo["name"]][1] . "</td>"); }
- print("</tr>");
- $personinfo[$finfo["person"]]["wip"]++;
- $wip_files[$finfo["name"]] = TRUE;
- }
-
- print ("</table>\n<p> </p>\n");
-}
+// =========================================================================
+// Files table goes here
+// =========================================================================
+
+print <<<END_OF_MULTILINE
+<a name="files"></a>
+<table width="820" border="0" cellpadding="4" cellspacing="1" align="center">
+<tr>
+ <th rowspan="2" bgcolor="#666699">Translated file</th>
+ <th colspan="3" bgcolor="#666699">Revision</th>
+ <th colspan="3" bgcolor="#666699">Size in kB</th>
+ <th colspan="3" bgcolor="#666699">Age in days</th>
+ <th rowspan="2" bgcolor="#666699">Maintainer</th>
+ <th rowspan="2" bgcolor="#666699">Status</th>
+</tr>
+<tr>
+ <th bgcolor="#666699">en</th>
+ <th bgcolor="#666699">$LANG</th>
+ <th bgcolor="#666699">diff</th>
+ <th bgcolor="#666699">en</th>
+ <th bgcolor="#666699">$LANG</th>
+ <th bgcolor="#666699">diff</th>
+ <th bgcolor="#666699">en</th>
+ <th bgcolor="#666699">$LANG</th>
+ <th bgcolor="#666699">diff</th>
+</tr>
+END_OF_MULTILINE;
+
+// This was the previous directory [first]
+$prev_dir = $new_dir = "{$DOCDIR}en";
-$file_lists = ob_get_contents();
-ob_end_clean();
+// Go through all files collected
+foreach ($files_status as $num => $file) {
+
+ // Do not print out actual files
+ if ($file["mark"] == REV_ACTUAL) {
+ continue;
+ }
+
+ // 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 CVS repository's diff script
+ if ($file["revision"][2] != "n/a" && $file["revision"][2] !== 0) {
+ $file["short_name"] = "<a href=\"http://cvs.php.net/diff.php/" .
+ preg_replace( "'^".$DOCDIR."'", "phpdoc/",
+$file["full_name"]) .
+ "?r1=" . $file["revision"][1] .
+ "&r2=" . $file["revision"][0] .
+ CVS_OPT . "\">" . $file["short_name"] . "</a>";
+ }
-// If person list available (valid translation.xml file in lang)
-if (isset($translation["persons"])) {
- print("
- <table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\"
align=\"center\">
- <tr>
- <th rowspan=\"2\" bgcolor=\"#666699\"><a name=\"translators\"
class=\"ref\">Translator's name</a></th>
- <th rowspan=\"2\" bgcolor=\"#666699\">Contact email</th>
- <th rowspan=\"2\" bgcolor=\"#666699\">Nick</th>
- <th rowspan=\"2\" bgcolor=\"#666699\">CVS</th>
- <th colspan=\"6\" bgcolor=\"#666699\">Files maintained</th>
- </tr>
- <tr>
- <th bgcolor=\"#666699\">credits</th>
- <th bgcolor=\"#666699\">actual</th>
- <th bgcolor=\"#666699\">old</th>
- <th bgcolor=\"#666699\">veryold</th>
- <th bgcolor=\"#666699\">norev</th>
- <th bgcolor=\"#666699\">wip</th>
- </tr>
- ");
+ // Guess the new directory from the full name of the file
+ $new_dir = substr($file["full_name"], 0, strrpos($file["full_name"], "/"));
+
+ // If this is a new directory, put out dir headline
+ if ($new_dir != $prev_dir) {
+
+ // Drop out the unneded parts from the dirname...
+ $display_dir = str_replace("{$DOCDIR}en/", "", dirname($file["full_name"]));
+
+ // Print out directory header
+ print "<tr><th colspan=\"12\" height=\"3\"
+bgcolor=\"#666699\">$display_dir</th></tr>";
+
+ // Store the new actual directory
+ $prev_dir = $new_dir;
+ }
+
+ // Style attribute for all the cells
+ $style = 'style="' . $CSS[$file["mark"]] . '"';
+
+ // Write out the line for the current file
+ print "<tr>\n <td $style>{$file['short_name']}</td>\n".
+ " <td $style> {$file['revision'][0]}</td>" .
+ " <td $style> {$file['revision'][1]}</td>\n".
+ " <td $style align=\"right\"><b>{$file['revision'][2]}</b> </td>\n".
+ " <td $style align=\"right\">{$file['size'][0]} </td>\n".
+ " <td $style align=\"right\">{$file['size'][1]} </td>\n".
+ " <td $style align=\"right\"><b>{$file['size'][2]}</b> </td>\n".
+ " <td $style align=\"right\">{$file['date'][0]} </td>\n".
+ " <td $style align=\"right\">{$file['date'][1]} </td>\n".
+ " <td $style align=\"right\"><b>{$file['date'][2]}</b> </td>\n".
+ " <td $style align=\"center\">{$file['maintainer']} </td>\n".
+ " <td $style align=\"center\">{$file['status']} </td>\n</tr>\n";
+
+}
+
+print("</table>\n<p> </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) {
+
+ // Figure out, if we need to use optional date and
+ // revision columns (if there is no file with that parameter,
+ // we won't include the table column for that)
+ $using_date = FALSE; $using_rev = FALSE;
+ foreach ($translation["files"] as $file) {
+ if (isset($file["date"])) { $using_date = TRUE; }
+ if (isset($file["revision"])) { $using_rev = TRUE; }
+ }
- foreach($translation["persons"] as $num => $person) {
- if ($person["cvs"] === "yes") { $cvsu = "yes"; $col = "\"#eee8aa\""; }
- else { $cvsu = "no"; $col = "\"#dcdcdc\""; }
- $person["email"] = str_replace("@", "<small>:at:</small>", $person["email"]);
- $pi = $personinfo[$person["nick"]];
- print("<tr bgcolor=$col><td><a name=\"maint$num\">$person[name]</a></td>" .
-
"<td>$person[email] </td><td>$person[nick] </td><td>$cvsu </td>" .
- "<td align=\"center\">$pi[credits] </td><td
align=\"center\">$pi[actual] </td>".
- "<td align=\"center\">$pi[old] </td><td
align=\"center\">$pi[veryold] </td>".
- "<td align=\"center\">$pi[norev] </td><td
align=\"center\">$pi[wip] </td></tr>\n");
- }
+ // Print out files table header
+ print '
+ <a name="wip"></a>
+ <table width="820" border="0" cellpadding="4" cellspacing="1" align="center">
+ <tr>
+ <th bgcolor="#666699">Work in progress files</th>
+ <th bgcolor="#666699">Translator</th>
+ <th bgcolor="#666699">Type</th>
+ ';
- print ("</table>\n<p> </p>\n");
-}
+ // Print out date and revision columns if needed
+ if ($using_date) {
+ print '<th bgcolor="#666699">Date</th>' . "\n";
+ }
+ if ($using_rev) {
+ print '<th bgcolor="#666699">CO-Revision</th>' .
+ '<th bgcolor="#666699">EN-Revision</th>' . "\n";
+ }
+ print "</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
+ print "<tr bgcolor=\"#DDDDDD\"><td>$finfo[name]</td>" .
+ "<td>$finfo[person]</td><td>$finfo[type]</td>";
+
+ // If we need the date column, print it out
+ if ($using_date) {
+ print "<td>$finfo[date]</td>";
+ }
+
+ // If we need the revision column, print it out
+ if ($using_rev) {
+ print "<td>$finfo[revision]</td><td>1." .
+ $missing_files[$finfo["name"]][1] .
+ "</td>";
+ }
+
+ // End the line
+ print "</tr>";
-print($file_lists);
+ // Collect files in WIP list
+ $wip_files[$finfo["name"]] = TRUE;
+ }
+
+ print "</table>\n<p> </p>\n";
+}
-// Files without revision comment
-$count = count($miss_tag);
+// Files translated, but without a revision comment
+$count = count($missing_tags);
if ($count > 0) {
- print("<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\"
align=\"center\">\n".
- " <tr><th bgcolor=\"#666699\"><b>Files without Revision-comment ($count
files):</b></th></tr>\n");
- foreach($miss_tag as $val) {
- print(" <tr><td bgcolor=\"#DDDDDD\"> $val</td></tr>\n");
- }
- print("</table>\n<p> </p>\n");
-}
-
-// Clear out work in progress files from available files
-if (isset($wip_files)) {
- foreach($wip_files as $fname => $one) {
- if (isset($missed_files[$fname])) { unset($missed_files[$fname]); }
- }
-}
-if (isset($wip_others)) {
- foreach($wip_others as $file => $one) {
- if (isset($missed_files[$one['name']])) { unset($missed_files[$one['name']]); }
- }
+ print "<a name=\"misstags\"></a>" .
+ "<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\"
+align=\"center\">\n".
+ " <tr><th bgcolor=\"#666699\"><b>Files without Revision-comment ($count
+files):</b></th></tr>\n";
+ foreach($missing_tags as $val) {
+ print " <tr><td bgcolor=\"#DDDDDD\"> $val</td></tr>\n";
+ }
+ print "</table>\n<p> </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($missed_files);
+$count = count($missing_files);
if ($count > 0) {
- print("<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\"
align=\"center\">\n".
- " <tr><th colspan=\"2\" bgcolor=\"#666699\"><b><a name=\"avail\"
class=\"ref\">Available for translation</a> ($count files):</b></th></tr>\n");
- foreach($missed_files as $file => $info) {
- print(" <tr><td bgcolor=\"#DDDDDD\"> $file</td>".
- "<td align=\"right\" bgcolor=\"#DDDDDD\">$info[0] kB </td></tr>\n");
- }
- print("</table>\n<p> </p>\n");
+ print "<a name=\"missfiles\"></a>" .
+ "<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\"
+align=\"center\">\n" .
+ " <tr><th colspan=\"2\" bgcolor=\"#666699\"><b><a name=\"avail\"
+class=\"ref\">" .
+ " Available for translation</a> ($count files):</b></th></tr>\n";
+ foreach($missing_files as $file => $info) {
+ print " <tr><td bgcolor=\"#DDDDDD\"> $file</td>" .
+ " <td align=\"right\" bgcolor=\"#DDDDDD\">$info[0] kB
+ </td></tr>\n";
+ }
+ print "</table>\n<p> </p>\n";
}
// All OK, end the file
-print("</body>\n</html>\n");
+print "</body>\n</html>\n";
?>