1 |
#!/usr/bin/perl |
2 |
use strict; |
3 |
require 'html-content.pl'; |
4 |
our $LIST; |
5 |
|
6 |
my %argv; |
7 |
for (@ARGV) { |
8 |
$argv{$1} = 1 if /^--([^\s=]+)$/; |
9 |
} |
10 |
if ($argv{help}) { |
11 |
require Pod::Usage; |
12 |
Pod::Usage::pod2usage (-exitval => 0, -verbose => 1); |
13 |
} |
14 |
|
15 |
sub add (%) { |
16 |
my (%opt) = @_; |
17 |
push @{$opt{table}->[0]}, $opt{name}; |
18 |
push @{$opt{table}->[$_]}, [] for 1..$#{$opt{table}}; |
19 |
for my $class (sort keys %{$opt{list}}) { |
20 |
ELEMENT: for my $element (split /[\s|]+/, $opt{list}->{$class}) { |
21 |
for (@{$opt{table}}) { |
22 |
if ($_->[0] eq $element) { |
23 |
push @{$_->[-1]}, $class; |
24 |
next ELEMENT; |
25 |
} |
26 |
} |
27 |
my $row = [$element]; |
28 |
for (my $i = $#{$opt{table}->[0]} - 1; $i > 0; $i--) { |
29 |
push @$row, []; |
30 |
} |
31 |
push @$row, [$class]; |
32 |
push @{$opt{table}}, $row; |
33 |
} |
34 |
} |
35 |
} |
36 |
|
37 |
sub element ($) { |
38 |
my $el = shift; |
39 |
if ($el =~ /[A-Z%]/) { |
40 |
qq<<code>$el</code>>; |
41 |
} else { |
42 |
qq<<code class="HTMLe">$el</code>>; |
43 |
} |
44 |
} |
45 |
|
46 |
sub elements ($) { |
47 |
join ', ', map {element $_} @{$_[0]}; |
48 |
} |
49 |
|
50 |
sub serialize ($$) { |
51 |
my ($tbl, $span) = @_; |
52 |
my $r = q<<table border><thead><tr>>; |
53 |
$r .= join '', map {qq<<th>$_</th>>} @{$tbl->[0]}; |
54 |
$r .= q<</tr></thead><tbody>>; |
55 |
for my $i (1..$#$tbl) { |
56 |
$r .= q<<tr>>; |
57 |
$r .= q<<th>>.element ($tbl->[$i]->[0]).q<</th>>; |
58 |
for my $j (1..$#{$tbl->[$i]}) { |
59 |
if ($tbl->[$i]->[$j]) { |
60 |
$r .= q{<td}; |
61 |
$r .= q< rowspan=">.$span->[$i]->[$j]->{row}.q<"> if $span->[$i]->[$j]->{row}; |
62 |
$r .= q< colspan=">.$span->[$i]->[$j]->{col}.q<"> if $span->[$i]->[$j]->{col}; |
63 |
$r .= q{>}; |
64 |
$r .= elements ($tbl->[$i]->[$j]) || '-'; |
65 |
$r .= q<</td>>; |
66 |
} |
67 |
} |
68 |
$r .= qq<</tr>\n>; |
69 |
} |
70 |
$r .= qq<</tbody></table>\n>; |
71 |
$r; |
72 |
} |
73 |
|
74 |
sub equal ($$) { |
75 |
my ($x, $y) = @_; |
76 |
return 0 unless @$x and @$y; |
77 |
for (0..$#$x) { |
78 |
return 0 unless $x->[$_] eq $y->[$_]; |
79 |
} |
80 |
return 1; |
81 |
} |
82 |
|
83 |
sub merge_row ($$) { |
84 |
my ($tbl, $span) = @_; |
85 |
for my $i (1..($#$tbl-1)) { |
86 |
for my $j (1..$#{$tbl->[$i]}) { |
87 |
if ($tbl->[$i]->[$j]) { |
88 |
my $s = 1; |
89 |
for my $ii (($i+1)..$#$tbl) { |
90 |
if ($tbl->[$ii]->[$j] and |
91 |
$span->[$i]->[$j]->{col} == $span->[$ii]->[$j]->{col} and |
92 |
equal $tbl->[$i]->[$j] => $tbl->[$ii]->[$j]) { |
93 |
$s++; |
94 |
$tbl->[$ii]->[$j] = 0; |
95 |
} else { |
96 |
last; |
97 |
} |
98 |
} |
99 |
$span->[$i]->[$j]->{row} = $s if $s > 1; |
100 |
} |
101 |
} |
102 |
} |
103 |
} |
104 |
|
105 |
sub merge_col ($$) { |
106 |
my ($tbl, $span) = @_; |
107 |
for my $i (1..$#$tbl) { |
108 |
for my $j (1..($#{$tbl->[$i]}-1)) { |
109 |
if ($tbl->[$i]->[$j]) { |
110 |
my $s = 1; |
111 |
for my $jj (($j+1)..$#{$tbl->[$i]}) { |
112 |
if ($tbl->[$i]->[$jj] and |
113 |
$span->[$i]->[$j]->{row} == $span->[$i]->[$jj]->{row} and |
114 |
equal $tbl->[$i]->[$j] => $tbl->[$i]->[$jj]) { |
115 |
$s++; |
116 |
$tbl->[$i]->[$jj] = 0; |
117 |
} else { |
118 |
last; |
119 |
} |
120 |
} |
121 |
$span->[$i]->[$j]->{col} = $s if $s > 1; |
122 |
} |
123 |
} |
124 |
} |
125 |
} |
126 |
|
127 |
sub remove_empty_row ($) { |
128 |
my @tbl = @{+shift}; |
129 |
ROW: for (my $i = $#tbl; $i > 1; $i--) { |
130 |
for my $j (1..$#{$tbl[$i]}) { |
131 |
next ROW if not $tbl[$i]->[$j] or |
132 |
@{$tbl[$i]->[$j]}; |
133 |
} |
134 |
delete $tbl[$i]; |
135 |
} |
136 |
[grep defined $_, @tbl]; |
137 |
} |
138 |
|
139 |
my $tbl = [map {[$_]} '', qw/p div noframes center hr address blockquote pre xmp listing h1 h2 h3 h4 h5 h6 menu dir ul ol dl form isindex fieldset table %blocktext %heading %Heading.class Heading %block.forms %preformatted %list %lists %List.class List %BlkStruct.class %BlkPhras.class %BlkPres.class %Form.class Form %Fieldset.class %Table.class Table %BlkSpecial.class %Block.extra %block %Block %Block.class %Block.mix Block |
140 |
em strong code samp kbd var cite dfn abbr acronym q sub sup tt i b u strike s big small font basefont applet iframe object img map br span bdo input select textarea label button ruby a #PCDATA %phrase.basic %phrase.extra %logical.styles %phrase %InlPhras.class %fontstyle.basic %fontstyle.extra %font %physical.styles %fontstyle %InlPres.class %special.pre %special.basic %special.extra %special %InlStruct.class %I18n.class %InlSpecial.class %form %formctrl %form.fields %inline.forms %InlForm.class Formctrl %Ruby.class %Anchor.class %InlNoRuby.class %InlNoAnchor.class %Inline.extra %text %inline %Inline %Inline.class %Inline.mix Inline |
141 |
ins del script noscript %Edit.class %Script.class %Misc.extra %misc.inline %misc %Misc.class |
142 |
%flow %Flow %Flow.class %Flow.mix Flow/]; |
143 |
my @span; |
144 |
|
145 |
for (@$LIST) { |
146 |
next if $argv{'no-strict'} and $_->{name} =~ /Strict|ISO-HTML|XHTML 1.1/ |
147 |
and not $_->{name} =~ /Legacy/; |
148 |
next if $argv{'no-transitional'} and $_->{name} =~ /Transitional|Legacy/ |
149 |
and not $_->{name} =~ /Frameset/; |
150 |
next if $argv{'no-frameset'} and $_->{name} =~ /Frameset/ |
151 |
and not $_->{name} =~ /Transitional/; |
152 |
add table => $tbl, name => $_->{name}, list => $_->{class}; |
153 |
} |
154 |
$tbl = remove_empty_row $tbl; |
155 |
merge_col $tbl, \@span; |
156 |
merge_row $tbl, \@span; |
157 |
|
158 |
print STDOUT qq<<!DOCTYPE table SYSTEM>\n>; |
159 |
print STDOUT serialize $tbl, \@span; |
160 |
|
161 |
=head1 NAME |
162 |
|
163 |
mkclstbl - HTML Element Type Class History Table Generator |
164 |
|
165 |
=head1 SYNOPSIS |
166 |
|
167 |
mkclstbl.pl [--no-strict] [--no-transitional] [--no-frameset] > table.html |
168 |
mkclstbl.pl --help |
169 |
|
170 |
=head1 DESCRIPTION |
171 |
|
172 |
This script generates an HTML table that describes what element type belongs |
173 |
what element class(es) in versions of HTML. |
174 |
|
175 |
=head1 OPTIONS |
176 |
|
177 |
This script has four arguments: |
178 |
|
179 |
=over 4 |
180 |
|
181 |
=item --help |
182 |
|
183 |
Show help message. |
184 |
|
185 |
=item --no-frameset |
186 |
|
187 |
Omit some columns that describes Frameset DTDs. |
188 |
|
189 |
=item --no-strict |
190 |
|
191 |
Omit some columns that describes Strict DTDs, ISO-HTML, XHTML 1.1 or |
192 |
XHTML m12n Abstract Modules. |
193 |
|
194 |
=item --no-transitional |
195 |
|
196 |
Omit some columns that describes Transitional DTDs. |
197 |
|
198 |
=back |
199 |
|
200 |
=head1 SEE ALSO |
201 |
|
202 |
HTML Specifications and DTDs. |
203 |
|
204 |
<http://suika.fam.cx/www/2004/html/>. |
205 |
|
206 |
=head1 LICENSE |
207 |
|
208 |
Copyright 2004 Wakaba <w@suika.fam.cx> |
209 |
|
210 |
This program is free software; you can redistribute it and/or |
211 |
modify it under the same terms as Perl itself. |
212 |
|
213 |
=cut |
214 |
|
215 |
# $Date: 2004/07/03 06:24:06 $ |