#!/usr/bin/perl
# convert a ports INDEX file to XML files
#
# by John Fieber <jfieber@FreeBSD.org>
# Mon May 13 10:31:58 EST 1996
# $FreeBSD$
# The FreeBSD Japanese Documentation Project
# Original revision: r50931
############################################################
use strict;
use POSIX;
use IO::File;
my $base = "";
my $baseHTTP = "";
my $urlcgi = "";
my $packagesURL = "";
my $today = getdate();
my %p = ();
# Load local config file. You can override in portindex.conf
# the variables for the default web and the ftp server. This
# make it easy to maintain a local web mirror and let the
# URL point to yourself and not to the standard FreeBSD FTP server.
my $config = $0 . '.' . 'conf';
do $config if -f $config;
# This is the base of where we ftp stuff from
my $ftpserver;
if ($ENV{'MASTER_FTP_SERVER'}) {
$ftpserver = $ENV{'MASTER_FTP_SERVER'};
} else {
$ftpserver = 'ftp://ftp.FreeBSD.org' if !$ftpserver;
}
my $baseFTP = "$ftpserver/pub/FreeBSD/ports/ports";
my $baseSVNWEB = 'https://svnweb.FreeBSD.org/ports/head/';
$packagesURL = "$ftpserver/pub/FreeBSD/ports/i386/packages-stable/All/"
if !$packagesURL;
# support tar on the fly or gzip'ed tar on the fly
my $ftparchive = '';
$ftparchive = '.tar' if !defined $ftparchive;
my %packages = ();
my %category_description = ();
my @category_groups = ();
my %category_groups = ();
packages_exist('packages.exists');
category_description(($ARGV[1] || '.') . '/categories' );
category_groups(($ARGV[1] || '.') . '/categories.descriptions' );
main();
sub getdate {
# return ": $year 年 $mon 月 $mday 日";
return POSIX::strftime("%d-%B-%Y", localtime);
}
sub header {
my $fh = shift;
my $htext = shift;
#local($fh, $htext) = @_;
print $fh <<EOF;
<?xml version="1.0" encoding="euc-jp"?>
<!DOCTYPE html PUBLIC "-//FreeBSD//DTD XHTML 1.0 Transitional-Based Extension//EN"
"http://www.FreeBSD.org/XML/share/xml/xhtml10-freebsd.dtd" [
<!ENTITY base '..'>
<!ENTITY % navinclude.ports "INCLUDE">
<!ENTITY % ports.ent SYSTEM "ports.ent">
%ports.ent;
<!ENTITY email 'ports'>
%statistics.ent;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>$htext</title>
<cvs:keyword xmlns:cvs=\"http://www.FreeBSD.org/XML/CVS\">x x x $today x x x</cvs:keyword>
</head>
<body class="navinclude.port">
&searchform;
<hr/>
EOF
}
sub footer {
my $fh = shift;
my $ftext = shift;
#local ($fh, $ftext) = @_;
print $fh <<EOF;
$ftext
</body>
</html>
EOF
}
sub packages_exist {
my $file=shift;
my %p;
#local($file, *p) = @_;
open(P, $file) || do {
warn "open $file: $!\n";
warn "Cannot create packages links\n";
return 1;
};
while(<P>) {
chop;
$packages{$_} = 1;
}
close P;
}
sub category_description {
my $file = shift;
open(P, $file) || do {
warn "open $file: $!\n";
warn "Cannot find category description\n";
return 1;
};
while(<P>) {
# ignore comments
next if /^\s*#/;
if (/^\s*([^,]+),\s*"([^"]+)",\s*([A-Z]+)/) {
$category_description{$1}{desc}=$2;
$category_description{$1}{group}=$3;
}
}
close P;
}
sub category_groups {
my $file = shift;
open(P, $file) || do {
warn "open $file: $!\n";
warn "Cannot find category groups\n";
return 1;
};
while(<P>) {
# ignore comments
next if /^\s*#/;
if (/^\s*([^,]+),\s*(.+)/) {
$category_groups{$1}=$2;
push(@category_groups,$1);
}
}
close P;
}
sub main {
my @master=();
my %stats;
my %catkey;
my %data;
my %descLANG;
my $portnumber = 0;
my $sep = "<b>:</b>";
my $moutf = new IO::File;
my $outf = new IO::File;
my $mindex = new IO::File;
my $statistics = new IO::File;
my $lloc;
# 'COMMENT' translation database
if (open(COMF, "comments.ja")) {
while (<COMF>) {
($a, $b) = split('\|');
next if !defined($b);
chop($b);
$b =~ s/&/&/g;
$b =~ s/</</g;
$b =~ s/>/>/g;
$descLANG{$a} = $b;
}
}
open(INDEX, $ARGV[0]);
$portnumber = "0";
while (<INDEX>) {
chop;
s/&/&/g;
s/</</g;
s/>/>/g;
# Read a record
my ($name, $loc, $prefix, $desc, $ldesc, $owner, $cats,
$bdep, $rdep, $www) = split('\|');
# Check for double hyphens in the name (--).
$name =~ s/--/-/g;
# Split the categories into an array
my @cat = split("[ \t]+", $cats);
$catkey{$name} = $cat[0];
# desc translation
($lloc = $loc) =~ s@^/usr/ports/@@;
$desc = $descLANG{$lloc}
if ($descLANG{$lloc} ne '');
# figure out the FTP url
$loc =~ s%/usr/ports/%$baseSVNWEB%;
$ldesc =~ s%/usr/ports/%$baseSVNWEB%;
$ldesc .= '?revision=HEAD';
foreach my $i (sort(@cat)) {
$stats{$i}++;
# The name description and maintainer
$name =~ s/,.*//g;
$name =~ s/\++//g;
$data{$i} .= "<dt><b><a name=\"$name\"></a><a href=\"${loc}${ftparchive}\">$name</a></b></dt> ";
$data{$i} .= "<dd>$desc<br/><a href=\"$ldesc\">詳しい説明</a>";
if ($packages{"$name.tbz"}) {
$data{$i} .= qq{ | <a href="$packagesURL$name.tbz">パッケージ</a>};
} elsif ($packages{"$name.tgz"}) {
$data{$i} .= qq{ | <a href="$packagesURL$name.tgz">パッケージ</a>};
}
$data{$i} .= qq{ | <a href="$loc/?view=log">変更点</a>};
if ($www ne "") {
$data{$i} .= qq{ | <a href="$www">メインウェブサイト</a>};
}
my $ownerurl = $owner;
$ownerurl =~ s/</</g;
$ownerurl =~ s/>/>/g;
$data{$i} .=
"<br/><i>保守担当者:</i> <a href=\"mailto:$ownerurl\">$owner</a>";
# If there are any dependencies, list them
if ($bdep ne "" || $rdep ne "") {
$data{$i} .= "<br/><i>必要なもの:</i> ";
my @dep = split(/ /, "$bdep $rdep");
my $last = '';
foreach my $j (sort @dep) {
next if $j eq $last;
$last = $j;
$data{$i} .= " <a href=\"##$j##.html#$j\">$j</a>,";
}
# remove the trailing comma
chop $data{$i};
}
# If the port is listed in more than one category, throw
# in some cross references
if ($#cat > 0) {
$data{$i} .= "<br/><em>ここにも含まれています:</em> ";
foreach my $j (@cat) {
if ($j ne $i) {
if ($j eq $cat[0]) {
$data{$i} .= " <strong><a href=\"$j.html#$name\">\u$j</a></strong>,";
}
else {
$data{$i} .= " <a href=\"$j.html#$name\">\u$j</a>,";
}
}
}
# remove the trailing comma
chop($data{$i});
}
$data{$i} .= "<p></p></dd>\n"
}
# Add an entry to the master index
# workaround XML syntax, `--' is not allowed in comments
my $sname = $name;
$sname =~ s/--/-=/g;
$master[$portnumber] =
"<!-- $sname --><strong><a href=\"$cat[0].html#$name\">$name</a></strong> " .
" -- <em>$desc</em><br/>\n";
$portnumber++;
}
# create categories-grouped.xml and <category>.xml
$moutf->open(">categories-grouped.xml");
header($moutf, "FreeBSD Ports -- グループによる分類");
print $moutf <<EOF;
<a name=\"top\"></a>
EOF
if ($portnumber eq '0') {
print $moutf "<p>none found</p>\n";
} else {
foreach my $cg (@category_groups) {
print $moutf "<h3>",$category_groups{$cg},"</h3>\n";
print $moutf "<ul>\n";
foreach my $key (sort(keys(%stats))) {
if (!defined $category_description{$key}{group}) {
warn "Warning: no category_description/group for $key, ignore\n";
next;
}
next if ($category_description{$key}{group} ne $cg);
# For the master file...
print $moutf
"<li><a href=\"$key.html\">\u$key</a> <em>($stats{$key})</em>";
if ($category_description{$key}{desc}) {
print $moutf " -- " . $category_description{$key}{desc};
}
# Someone forgot to add a category to the description file
# or there is a typo in the category field.
else {
warn "No description found for category: ``$key''!\n";
warn "Please fix me or send an E-Mail to doc\@FreeBSD.org\a\n";
sleep(3);
}
print $moutf "</li>\n";
# Create the category file
$outf->open(">$key.xml");
header($outf, "FreeBSD Ports: \u$key");
if ($category_description{$key}{desc}) {
print $outf "<h3>", $category_description{$key}{desc}, "</h3>\n";
}
print $outf "<dl>\n";
my $d = join("\n", sort(split(/\n/, $data{$key})));
$d =~ s/##([^#]*)##/$catkey{$1}/g;
print $outf $d;
print $outf "</dl>\n";
footer($outf, "<p></p><a href=\"#top\">top</a>" .
" -- <a href=\"master-index.html\">Index</a>");
$outf->close;
}
print $moutf "</ul>\n";
}
}
footer($moutf, "");
$moutf->close;
# create categories-alpha.xml
$moutf->open(">categories-alpha.xml");
header($moutf, "FreeBSD Ports -- アルファベット順");
print $moutf <<EOF;
<a name=\"top\"></a>
EOF
if ($portnumber eq '0') {
print $moutf "<p>none found</p>\n";
} else {
print $moutf "<ul>\n";
foreach my $key (sort(keys(%stats))) {
print $moutf
"<li><a href=\"$key.html\">\u$key</a> <em>($stats{$key})</em>";
if ($category_description{$key}{desc}) {
print $moutf " -- " . $category_description{$key}{desc};
}
print $moutf "</li>\n";
}
print $moutf "</ul>\n";
}
footer($moutf, "");
$moutf->close;
# Create master-index.xml
$mindex->open(">master-index.xml");
header($mindex, "FreeBSD Ports Collection 一覧");
print $mindex "<p>\n";
print $mindex sort @master;
print $mindex "</p>";
footer($mindex, "<a href=\"#top\">top</a>");
$mindex->close;
# Create statistics.ent
$statistics->open(">statistics.ent");
print $statistics "<!ENTITY ports.count '$portnumber'>\n";
$statistics->close;
close(INDEX);
}