#!/usr/bin/perl


@general=(
['Lo', 'Letter, Other',                                                            'rgb(100%,50%,50%)'],
['Lm', 'Letter, Modifier',                                                         'rgb(100%,50%,50%)',  'B', 'rgb(80%,100%,0%)'],
['Lu', 'Letter, Uppercase',                                                        'rgb(100%,50%,50%)',  'B', 'rgb(0%,100%,40%)'],
['Lt', 'Letter, Titlecase',                                                        'rgb(100%,50%,50%)',  'B', 'rgb(0%,40%,100%)'],
['Ll', 'Letter, Lowercase',                                                        'rgb(100%,50%,50%)',  'B', 'rgb(80%,0%,100%)'],

['Mc', 'Mark, Spacing Combining',                                                  'rgb(100%,100%,50%)', 'B', 'rgb(100%,0%,0%)'],
['Me', 'Mark, Enclosing',                                                          'rgb(100%,100%,50%)', 'B', 'rgb(0%,100%,0%)'],
['Mn', 'Mark, Non-Spacing',                                                        'rgb(100%,100%,50%)', 'B', 'rgb(0%,0%,100%)'],

['Nd', 'Number, Decimal Digit',                                                    'rgb(50%,100%,50%)',  'B', 'rgb(100%,0%,0%)'],
['Nl', 'Number, Letter',                                                           'rgb(50%,100%,50%)',  'B', 'rgb(0%,0%,100%)'],
['No', 'Number, Other',                                                            'rgb(50%,100%,50%)'],

['Pc', 'Punctuation, Connector',                                                   'rgb(50%,100%,100%)', 'B', 'rgb(0%,100%,25%)'],
['Pd', 'Punctuation, Dash',                                                        'rgb(50%,100%,100%)', 'B', 'rgb(0%,25%,100%)'],
['Ps', 'Punctuation, Open',                                                        'rgb(50%,100%,100%)', 'L', 'rgb(100%,0%,75%)'],
['Pe', 'Punctuation, Close',                                                       'rgb(50%,100%,100%)', 'R', 'rgb(100%,0%,75%)'],
['Pi', 'Punctuation, Initial quote (may behave like Ps or Pe depending on usage)', 'rgb(50%,100%,100%)', 'L', 'rgb(100%,75%,0%)'],
['Pf', 'Punctuation, Final quote (may behave like Ps or Pe depending on usage)',   'rgb(50%,100%,100%)', 'R', 'rgb(100%,75%,0%)'],
['Po', 'Punctuation, Other',                                                       'rgb(50%,100%,100%)'],

['Sc', 'Symbol, Currency',                                                         'rgb(50%,50%,100%)',  'B', 'rgb(100%,100%,0%)'],
['Sk', 'Symbol, Modifier',                                                         'rgb(50%,50%,100%)',  'B', 'rgb(0%,100%,100%)'],
['Sm', 'Symbol, Math',                                                             'rgb(50%,50%,100%)',  'B', 'rgb(100%,0%,100%)'],
['So', 'Symbol, Other',                                                            'rgb(50%,50%,100%)'],

['Zl', 'Separator, Line',                                                          'rgb(100%,50%,100%)', 'B', 'rgb(100%,0%,0%)'],
['Zp', 'Separator, Paragraph',                                                     'rgb(100%,50%,100%)', 'B', 'rgb(0%,100%,0%)'],
['Zs', 'Separator, Space',                                                         'rgb(100%,50%,100%)', 'B', 'rgb(0%,0%,100%)'],

['Cc', 'Other, Control',                                                           '',                   'B', 'rgb(90%,90%,90%)'],
['Cf', 'Other, Format',                                                            '',                   'B', 'rgb(80%,80%,80%)'],
['Cn', 'Other, Not Assigned (no characters in the file have this property)',       '',                   'B', 'rgb(70%,70%,70%)'],
['Co', 'Other, Private Use',                                                       '',                   'B', 'rgb(60%,60%,60%)'],
['Cs', 'Other, Surrogate',                                                         '',                   'B', 'rgb(50%,50%,50%)']
);


sub utf8 {
  if (@_[0]<0x80) {
    $result=pack 'C',@_[0];
  } elsif (@_[0]<0x800) {
    $result=pack 'C2',0xc0|@_[0]>>6,0x80|@_[0]&0x3f;
  } elsif (@_[0]<0x10000) {
    $result=pack 'C3',0xe0|@_[0]>>12,0x80|@_[0]>>6&0x3f,0x80|@_[0]&0x3f;
  } else {
    $result=pack 'C4',0xf0|@_[0]>>18,0x80|@_[0]>>12&0x3f,0x80|@_[0]>>6&0x3f,0x80|@_[0]&0x3f;
  }
  $result=(pack 'C3',0xe2,0x80,0xad).$result.(pack 'C3',0xe2,0x80,0xac) if $uni[@_[0]]{'bidirectional'} eq 'R' or $uni[@_[0]]{'bidirectional'} eq 'AL' or $uni[@_[0]]{'bidirectional'} eq 'RLE' or $uni[@_[0]]{'bidirectional'} eq 'RLO';
  $result;
}


for ($i=0;$general[$i][0];$i++) {
  $general=$general[$i][0];
  $general=~tr/A-Z/a-z/;
  $style=$style.".$general {";
  $style=$style."background-color:$general[$i][2]" if $general[$i][2];
  if ($general[$i][3] and $general[$i][4]) {
    $style=$style.'; ' if $general[$i][2];
    $style=$style.'border';
    if ($general[$i][3] eq 'L') {
      $style=$style.'-left';
    } elsif ($general[$i][3] eq 'R') {
      $style=$style.'-right';
    } elsif ($general[$i][3] eq 'T') {
      $style=$style.'-top';
    } elsif ($general[$i][3] eq 'B') {
      $style=$style.'-bottom';
    }
    $style=$style.":solid thick $general[$i][4]";
  }
  $style=$style."}\n";
}
$style=<<EOF;
<style type=\"text/css\"><!--
body {background-color:rgb(100%,100%,100%); color:rgb(0%,0%,0%)}
ul {line-height:200%}
$style
--></style>
EOF
$head=<<'EOF';
<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta name="robots" content="NOINDEX,NOFOLLOW">
<link rev="made" href="mailto:iwm@maid.org">
<link rel="index" href="index.html">
<link rel="icon" type="image/png" href="../icon.png" title="ISO-10646 Laboratory Icon">
EOF


###############################################################################
if (not open FH,'<UnicodeData.txt') {
  print STDERR "UnicodeData.txt is not opend.\n";
  exit -1;
}
while (<FH>) {
  chomp;
  ($code,
   $name,
   $general,
   $combining,
   $bidirectional,
   $decomposition,
   $decimal,
   $digit,
   $numeric,
   $mirror,
   $name1,
   $comment,
   $upper,
   $lower,
   $title)=split /;/;
  $code=hex $code;
  $upper=hex $upper;
  $lower=hex $lower;
  $title=hex $title;
  $uni[$code]{'name'}=$name;
  $uni[$code]{'general'}=$general;
  $uni[$code]{'bidirectional'}=$bidirectional;
  if ($decomposition) {
    if ($decomposition=~/^<(.+?)>\s(.*?)$/) {
      $uni[$code]{'decomposition'}="$1 $2";
      $decomposition{$1}=1;
    } else {
      $uni[$code]{'decomposition'}="canonical $decomposition";
    }
  }
  $range{$1}=$code if $name=~/^<(.*?),\s*First>$/i;
  if ($name=~/^<(.*?),\s*Last>$/i) {
    for ($i=$range{$1};$i<$code;$i++) {
      $uni[$i]{'name'}=$1;
      $uni[$i]{'general'}=$general;
    }
  }
}
close FH;


if (not open FH,'<Blocks.txt') {
  print STDERR "Blocks.txt is not opend.\n";
  exit -1;
}
$i=0;
while (<FH>) {
  chomp;
  s/#.*//;
  if (/([0-9a-zA-Z]+)..([0-9a-zA-Z]+);\s(.+)/) {
    $block[$i][0]=hex $1;
    $block[$i][1]=hex $2;
    $block[$i][2]=$3;
    $i++;
  }
}
close FH;


###############################################################################
print STDERR '-' x 79,"\n";
for ($i=0;$i<0x1100;$i++) {
  print STDERR '*' if $i%55==54;
  $file=sprintf '%04x.html',$i;
  if (not open FH,">$file") {
    print STDERR "$file is not opend.\n";
    exit -1;
  }
  print FH "$head$style";
  printf FH "<title>%04X00-%04XFF</title>\n",$i,$i;
  print FH <<'EOF';
</head>
<body>
<table border="1" cellspacing="0">
EOF
  $block='';
  for ($j=0;$block[$j][2];$j++) {
    if ($block[$j][0]<=$i*256+255 and $i*256<=$block[$j][1]) {
      $block=$block.',' if $block;
      $block=$block.$block[$j][2];
    }
  }
  print FH "<caption>$block</caption>\n" if $block;
  print FH <<'EOF';
<thead>
<tr align="center" valign="center"><th></th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th></tr>
</thead>
<tbody>
EOF
  for ($j=0;$j<16;$j++) {
    printf FH '<tr align="center" valign="center"><th>%X</th>',$j;
    for ($k=0;$k<16;$k++) {
      $code=$i*256+$j+$k*16;
      if ($uni[$code]{'general'}) {
        $general=$uni[$code]{'general'};
        $general=~tr/A-Z/a-z/;
        print FH "<td class=\"$general\">".((substr $general,0,1) eq 'c'?'&nbsp;':(utf8 $code)).'</td>';
      } else {
        print FH '<td>&nbsp;</td>';
      }
    }
    print FH "</tr>\n";
  }
  print FH "</tbody>\n</table>\n<ul>\n";
  if ($block) {
    for ($j=0;$block[$j][2];$j++) {
      printf FH "<li>%06X..%06X %s</li>\n",$block[$j][0],$block[$j][1],$block[$j][2] if $block[$j][0]<=$i*256+255 and $i*256<=$block[$j][1];
    }
    print FH "</ul>\n<ul>\n";
  }
  for ($j=0;$j<256;$j++) {
    $code=$i*256+$j;
    $name=$uni[$code]{'name'};
    $name=~s/</&lt;/g;
    $name=~s/>/&gt;/g;
    printf FH "<li>%06X $name</li>\n",$code;
  }
  print FH "</ul>\n</body>\n</html>\n";
  close FH;
}




###############################################################################
if (not open FH,'>index.html') {
  print STDERR "index.html is not opend.\n";
  exit -1;
}
print FH $head;
print FH <<'EOF';
<title>Unicode</title>
</head>
<frameset cols="20%,*">
<frame src="menu.html">
<frame src="row00.html" name="unicode_row">
</frameset>
</html>
EOF
close FH;


###############################################################################
if (not open FH,'>menu.html') {
  print STDERR "menu.html is not opend.\n";
  exit -1;
}
print FH $head;
print FH <<'EOF';
<title>Plane</title>
</head>
<body>
<ul>
EOF
for ($i=0;$i<0x11;$i++) {
  printf FH "<li><a href=\"row%02x.html\" target=\"unicode_row\">%02X</a></li>\n",$i,$i;
}
print FH <<'EOF';
<li><a href="general.html" target="unicode_row">General Category</a></li>
<li>Decomposition
  <ul>
  <li><a href="canonical.html" target="unicode_row">canonical</a></li>
EOF
foreach (sort keys %decomposition) {
  print FH "\t<li><a href=\"$_.html\" target=\"unicode_row\">$_</a></li>\n";
}
print FH <<'EOF';
  </ul>
</li>
</ul>
</body>
</html>
EOF
close FH;
$decomposition{'canonical'}=1;


###############################################################################
for ($i=0;$i<0x11;$i++) {
  $file=sprintf 'row%02x.html',$i;
  if (not open FH,">$file") {
    print STDERR "$file is not opend.\n";
    exit -1;
  }
  print FH $head;
  print FH <<'EOF';
<title>Row</title>
</head>
<frameset cols="20%,*">
EOF
  printf FH "<frame src=\"%02x.html\">\n<frame src=\"%02x00.html\" name=\"unicode_cell\">\n</frameset>\n</html>\n",$i,$i;
  close FH;
}


###############################################################################
for ($i=0;$i<0x11;$i++) {
  $file=sprintf '%02x.html',$i;
  if (not open FH,">$file") {
    print STDERR "$file is not opend.\n";
    exit -1;
  }
  print FH $head;
  print FH <<'EOF';
<title>Row</title>
</head>
<body>
<ul>
EOF
  for ($j=0;$j<0x100;$j++) {
    $block='';
    for ($k=0;$block[$k][2];$k++) {
      if ($block[$k][0]<=$i*65536+$j*256+255 and $i*65536+$j*256<=$block[$k][1]) {
        $block=$block.',' if $block;
        $block=$block.$block[$k][2];
      }
    }
    printf FH "<li><a href=\"%04x.html\" target=\"unicode_cell\">%04X</a>",$i*256+$j,$i*256+$j;
    print FH " $block" if $block;
    print FH "</li>\n";
  }
  print FH "</ul>\n</body>\n</html>\n";
  close FH;
}


###############################################################################
if (not open FH,'>general.html') {
  print STDERR "general.html is not opend.\n";
  exit -1;
}
print FH "$head$style";
print FH <<'EOF';
<title>General Category</title>
</head>
<body>
<ul style="line-height:200%">
EOF
for ($i=0;$general[$i][0];$i++) {
  $general=$general[$i][0];
  $general=~tr/A-Z/a-z/;
  print FH "<li><span class=\"$general\">$general[$i][0] $general[$i][1]</span></li>\n";
}
print FH "</ul>\n</body>\n</html>\n";
close FH;
###############################################################################
foreach $decomposition (sort keys %decomposition) {
  printf STDERR "\n%10s ",$decomposition;
  if (not open FH,">$decomposition.html") {
    print STDERR "$decomposition.html is not opend.";
    exit -1;
  }
  print FH "$head$style";
  print FH <<EOF;
<title>$decomposition</title>
</head>
<body>
<h1>$decomposition</h1>
<ul style=\"line-height:200%\">
EOF
  for ($i=0;$i<0x110000;$i++) {
    print STDERR '*' if $i%16384==16383;
    @decomposition=split /\s+/,$uni[$i]{'decomposition'};
    if ($decomposition[0] eq $decomposition) {
      printf FH '<li id="%06x"> ',$i,$i;
      $general=$uni[$i]{'general'};
      $general=~tr/A-Z/a-z/;
      print FH "<span class=\"$general\">" if $general;
      print FH (utf8 $i).' ' if (substr $general,0,1) ne 'c';
      printf FH '(%06X)',$i;
      print FH '</span>' if $general;
      print FH ' = ';
      for ($j=1;$decomposition[$j];$j++) {
        print FH ' + ' if $j > 1;
        $code=hex $decomposition[$j];
        $general=$uni[$code]{'general'};
        $general=~tr/A-Z/a-z/;
        if ($uni[$code]{'decomposition'}) {
          ($file)=split /\s+/,$uni[$code]{'decomposition'};
          if ($decomposition eq $file) {
            printf FH "<a href=\"#%06x\"",$code;
          } else {
            printf FH "<a href=\"$file.html#%06x\"",$code;
          }
          if ($general) {
            print FH " class=\"$general\">";
          } else {
            print FH '>';
          }
        } elsif ($general) {
          print FH "<span class=\"$general\">";
        }
        print FH (utf8 $code).' ' if (substr $general,0,1) ne 'c';
        printf FH '(%06X)',$code;
        if ($uni[$code]{'decomposition'}) {
          print FH '</a>';
        } elsif ($general) {
          print FH '</span>';
        }
      }
      print FH "</li>\n";
    }
  }
print FH "</ul>\n</body>\n</html>\n";
close FH;
}
print STDERR "\n";
