/[suikacvs]/webroot/www/2004/html/mkclstbl.pl
Suika

Contents of /webroot/www/2004/html/mkclstbl.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sat Jul 3 04:20:25 2004 UTC (21 years, 7 months ago) by wakaba
Branch: MAIN
File MIME type: text/plain
New

1 wakaba 1.1 #!/usr/bin/perl
2     use strict;
3    
4     my %argv;
5     for (@ARGV) {
6     $argv{$1} = 1 if /^--([^\s=]+)$/;
7     }
8     if ($argv{help}) {
9     require Pod::Usage;
10     Pod::Usage::pod2usage (-exitval => 0, -verbose => 1);
11     }
12    
13     sub add (%) {
14     my (%opt) = @_;
15     push @{$opt{table}->[0]}, $opt{name};
16     push @{$opt{table}->[$_]}, [] for 1..$#{$opt{table}};
17     for my $class (sort keys %{$opt{list}}) {
18     ELEMENT: for my $element (split /[\s|]+/, $opt{list}->{$class}) {
19     for (@{$opt{table}}) {
20     if ($_->[0] eq $element) {
21     push @{$_->[-1]}, $class;
22     next ELEMENT;
23     }
24     }
25     my $row = [$element];
26     for (my $i = $#{$opt{table}->[0]} - 1; $i > 0; $i--) {
27     push @$row, [];
28     }
29     push @$row, [$class];
30     push @{$opt{table}}, $row;
31     }
32     }
33     }
34    
35     sub element ($) {
36     my $el = shift;
37     if ($el =~ /[A-Z%]/) {
38     qq<<code>$el</code>>;
39     } else {
40     qq<<code class="HTMLe">$el</code>>;
41     }
42     }
43    
44     sub elements ($) {
45     join ', ', map {element $_} @{$_[0]};
46     }
47    
48     sub serialize ($$) {
49     my ($tbl, $span) = @_;
50     my $r = q<<table border><thead><tr>>;
51     $r .= join '', map {qq<<th>$_</th>>} @{$tbl->[0]};
52     $r .= q<</tr></thead><tbody>>;
53     for my $i (1..$#$tbl) {
54     $r .= q<<tr>>;
55     $r .= q<<th>>.element ($tbl->[$i]->[0]).q<</th>>;
56     for my $j (1..$#{$tbl->[$i]}) {
57     if ($tbl->[$i]->[$j]) {
58     $r .= q{<td};
59     $r .= q< rowspan=">.$span->[$i]->[$j]->{row}.q<"> if $span->[$i]->[$j]->{row};
60     $r .= q< colspan=">.$span->[$i]->[$j]->{col}.q<"> if $span->[$i]->[$j]->{col};
61     $r .= q{>};
62     $r .= elements ($tbl->[$i]->[$j]) || '-';
63     $r .= q<</td>>;
64     }
65     }
66     $r .= qq<</tr>\n>;
67     }
68     $r .= qq<</tbody></table>\n>;
69     $r;
70     }
71    
72     sub equal ($$) {
73     my ($x, $y) = @_;
74     return 0 unless @$x and @$y;
75     for (0..$#$x) {
76     return 0 unless $x->[$_] eq $y->[$_];
77     }
78     return 1;
79     }
80    
81     sub merge_row ($$) {
82     my ($tbl, $span) = @_;
83     for my $i (1..($#$tbl-1)) {
84     for my $j (1..$#{$tbl->[$i]}) {
85     if ($tbl->[$i]->[$j]) {
86     my $s = 1;
87     for my $ii (($i+1)..$#$tbl) {
88     if (equal $tbl->[$i]->[$j] => $tbl->[$ii]->[$j]) {
89     $s++;
90     $tbl->[$ii]->[$j] = 0;
91     } else {
92     last;
93     }
94     }
95     $span->[$i]->[$j]->{row} = $s if $s > 1;
96     }
97     }
98     }
99     }
100    
101     sub merge_col ($$) {
102     my ($tbl, $span) = @_;
103     for my $i (1..$#$tbl) {
104     for my $j (1..($#{$tbl->[$i]}-1)) {
105     if ($tbl->[$i]->[$j]) {
106     my $s = 1;
107     for my $jj (($j+1)..$#{$tbl->[$i]}) {
108     if ($tbl->[$i]->[$jj] and
109     $span->[$i]->[$j]->{row} == $span->[$i]->[$jj]->{row} and
110     equal $tbl->[$i]->[$j] => $tbl->[$i]->[$jj]) {
111     $s++;
112     $tbl->[$i]->[$jj] = 0;
113     } else {
114     last;
115     }
116     }
117     $span->[$i]->[$j]->{col} = $s if $s > 1;
118     }
119     }
120     }
121     }
122    
123     sub remove_empty_row ($) {
124     my @tbl = @{+shift};
125     ROW: for (my $i = $#tbl; $i > 1; $i--) {
126     for my $j (1..$#{$tbl[$i]}) {
127     next ROW if not $tbl[$i]->[$j] or
128     @{$tbl[$i]->[$j]};
129     }
130     delete $tbl[$i];
131     }
132     [grep defined $_, @tbl];
133     }
134    
135     my $list = [
136     {
137     name => q<HTML 2.0 (RFC 1868)>,
138     class => {
139     '%heading' => q"h1|h2|h3|h4|h5|h6",
140     '%list' => q"ul | ol | dir | menu",
141     '%font' => q"tt | b | i ",
142     '%phrase' => q"em | strong | code | samp | kbd | var | cite",
143     '%text' => q"#PCDATA | a | img | br | %phrase | %font",
144     '%block.forms' => q"blockquote | form | isindex",
145     '%preformatted' => q"pre | xmp | listing",
146     '%block' => q"p | %list | dl | %preformatted | %block.forms",
147     '%flow' => q"%text|%block",
148     '%body.content' => q"%heading | %text | %block | hr | address",
149     },
150     },
151     {
152     name => q<HTML 2.x (RFC 2070)>,
153     class => {
154     '%heading' => q"h1|h2|h3|h4|h5|h6",
155     '%list' => q"ul | ol | dir | menu",
156     '%font' => q"tt | b | i ",
157     '%phrase' => q"em | strong | code | samp | kbd | var | cite",
158     '%text' => q"#PCDATA|a|img|br|%phrase|%font|span|q|bdo|sup|sub",
159     '%block.forms' => q"blockquote | form | isindex",
160     '%preformatted' => q"pre | xmp | listing",
161     '%block' => q"p | %list | dl | %preformatted | %block.forms",
162     '%flow' => q"%text|%block",
163     '%body.content' => q"%heading | %text | %block | hr | address",
164     },
165     },
166     {
167     name => q<HTML 3.2>,
168     class => {
169     '%heading' => q"h1|h2|h3|h4|h5|h6",
170     '%list' => q"ul | ol | dir | menu",
171     '%preformatted' => q"pre | xmp | listing",
172     '%font' => q"tt | i | b | u | strike | big | small | sub | sup",
173     '%phrase' => q"em | strong | dfn | code | samp | kbd | var | cite",
174     '%special' => q"a | img | applet | font | basefont | br | script | map",
175     '%form' => q"input | select | textarea",
176     '%text' => q"#PCDATA | %font | %phrase | %special | %form",
177     '%block' => q"p | %list | %preformatted | dl | div | center |
178     blockquote | form | isindex | hr | table",
179     '%flow' => q"%text | %block",
180     '%body.content' => q"%heading | %text | %block | address",
181     },
182     },
183     {
184     name => q<HTML 4.01 Transitional / Frameset>,
185     class => {
186     '%heading' => q<h1|h2|h3|h4|h5|h6>,
187     '%list' => q/ul | ol | dir | menu/,
188     '%preformatted' => q"pre",
189     '%fontstyle' => q"tt | i | b | u | s | strike | big | small",
190     '%phrase' => q"em | strong | dfn | code | samp | kbd | var | cite | abbr | acronym",
191     '%special' => q"a | img | applet | object | font | basefont | br | script |
192     map | q | sub | sup | span | bdo | iframe",
193     '%formctrl' => q"input | select | textarea | label | button",
194     '%inline' => q"#PCDATA | %fontstyle | %phrase | %special | %formctrl",
195     '%block' => q "p | %heading | %list | %preformatted | dl | div | center |
196     noscript | noframes | blockquote | form | isindex | hr |
197     table | fieldset | address",
198     '%flow' => q"%block | %inline",
199     },
200     },
201     {
202     name => q<HTML 4.01 Strict>,
203     class => {
204     '%heading' => q<h1|h2|h3|h4|h5|h6>,
205     '%list' => q/ul|ol/,
206     '%preformatted' => q"pre",
207     '%fontstyle' => q"tt | i | b | big | small",
208     '%phrase' => q"em | strong | dfn | code | samp | kbd | var | cite | abbr | acronym",
209     '%special' => q"a | img | object | br | script | map | q | sub | sup | span | bdo",
210     '%formctrl' => q"input | select | textarea | label | button",
211     '%inline' => q"#PCDATA | %fontstyle | %phrase | %special | %formctrl",
212     '%block' => q "p | %heading | %list | %preformatted | dl | div | noscript |
213     blockquote | form | hr | table | fieldset | address",
214     '%flow' => q"%block | %inline",
215     },
216     },
217     {
218     name => q<ISO-HTML>,
219     class => {
220     '%special' => q"a | bdo | br | img | object |
221     map | q | span",
222     '%logical.styles' => q"abbr | acronym | cite | code | dfn | em |
223     kbd | samp | strong | var",
224     '%physical.styles' => q"b | i | sub | sup | tt",
225     '%block' => q"blockquote | div | dl | fieldset | form |
226     hr | ol | p | pre | table | ul",
227     '%form.fields' => q"button | input | label | select | textarea",
228     '%text' => q"#PCDATA | %physical.styles | %logical.styles | %special
229     | %form.fields ",
230     '%section.content' => q"%block | %text | address",
231     '%table.content' => q"%block | %text ",
232     },
233     },
234     {
235     name => q<XHTML 1.0 FE Transitional>,
236     class => {
237     '%special' => q"br | span | bdo | object | applet | img | map | iframe",
238     '%fontstyle' => q"tt | i | b | big | small | u
239     | s | strike |font | basefont",
240     '%phrase' => q"em | strong | dfn | code | q | sub | sup |
241     samp | kbd | var | cite | abbr | acronym",
242     '%inline.forms' => q"input | select | textarea | label | button",
243     '%misc' => q"ins | del | script | noscript",
244     '%inline' => q"a | %special | %fontstyle | %phrase | %inline.forms",
245     '%Inline' => q"#PCDATA | %inline | %misc",
246     '%heading' => q"h1|h2|h3|h4|h5|h6",
247     '%lists' => q"ul | ol | dl | menu | dir",
248     '%blocktext' => q"pre | hr | blockquote | address | center | noframes",
249     '%block' => q"p | %heading | div | %lists | %blocktext | isindex |fieldset | table",
250     '%Block' => q"%block | form | %misc",
251     '%Flow' => q"#PCDATA | %block | form | %inline | %misc",
252     },
253     },
254     {
255     name => q<XHTML 1.0 FE Frameset>,
256     class => {
257     '%special' => q"br | span | bdo | object | applet | img | map | iframe",
258     '%fontstyle' => q"tt | i | b | big | small | u
259     | s | strike |font | basefont",
260     '%phrase' => q"em | strong | dfn | code | q | sub | sup |
261     samp | kbd | var | cite | abbr | acronym",
262     '%inline.forms' => q"input | select | textarea | label | button",
263     '%misc' => q"ins | del | script | noscript",
264     '%inline' => q"a | %special | %fontstyle | %phrase | %inline.forms",
265     '%Inline' => q"#PCDATA | %inline | %misc",
266     '%heading' => q"h1|h2|h3|h4|h5|h6",
267     '%lists' => q"ul | ol | dl | menu | dir",
268     '%blocktext' => q"pre | hr | blockquote | address | center ",
269     '%block' => q"p | %heading | div | %lists | %blocktext | isindex |fieldset | table",
270     '%Block' => q"%block | form | %misc",
271     '%Flow' => q"#PCDATA | %block | form | %inline | %misc",
272     },
273     },
274     {
275     name => q<XHTML 1.0 FE Strict>,
276     class => {
277     '%special' => q"br | span | bdo | object | img | map",
278     '%fontstyle' => q"tt | i | b | big | small",
279     '%phrase' => q"em | strong | dfn | code | q | sub | sup |
280     samp | kbd | var | cite | abbr | acronym",
281     '%inline.forms' => q"input | select | textarea | label | button",
282     '%misc' => q"ins | del | script | noscript",
283     '%inline' => q"a | %special | %fontstyle | %phrase | %inline.forms",
284     '%Inline' => q"#PCDATA | %inline | %misc",
285     '%heading' => q"h1|h2|h3|h4|h5|h6",
286     '%lists' => q"ul | ol | dl",
287     '%blocktext' => q"pre | hr | blockquote | address",
288     '%block' => q"p | %heading | div | %lists | %blocktext | fieldset | table",
289     '%Block' => q"%block | form | %misc",
290     '%Flow' => q"#PCDATA | %block | form | %inline | %misc",
291     },
292     },
293     {
294     name => q<XHTML 1.0 SE Transitional>,
295     class => {
296     '%special.extra' => q"object | applet | img | map | iframe",
297     '%special.basic' => q"br | span | bdo",
298     '%special' => q"%special.basic | %special.extra",
299     '%fontstyle.extra' => q"big | small | font | basefont",
300     '%fontstyle.basic' => q"tt | i | b | u
301     | s | strike ",
302     '%fontstyle' => q"%fontstyle.basic | %fontstyle.extra",
303     '%phrase.extra' => q"sub | sup",
304     '%phrase.basic' => q"em | strong | dfn | code | q |
305     samp | kbd | var | cite | abbr | acronym",
306     '%phrase' => q"%phrase.basic | %phrase.extra",
307     '%inline.forms' => q"input | select | textarea | label | button",
308     '%misc' => q"noscript | %misc.inline",
309     '%misc.inline' => q"ins | del | script",
310     '%inline' => q"a | %special | %fontstyle | %phrase | %inline.forms",
311     '%Inline' => q"#PCDATA | %inline | %misc.inline",
312     '%heading' => q"h1|h2|h3|h4|h5|h6",
313     '%lists' => q"ul | ol | dl | menu | dir",
314     '%blocktext' => q"pre | hr | blockquote | address | center | noframes",
315     '%block' => q"p | %heading | div | %lists | %blocktext | isindex |fieldset | table",
316     '%Flow' => q"#PCDATA | %block | form | %inline | %misc",
317     },
318     },
319     {
320     name => q<XHTML 1.0 SE Frameset>,
321     class => {
322     '%special.extra' => q"object | applet | img | map | iframe",
323     '%special.basic' => q"br | span | bdo",
324     '%special' => q"%special.basic | %special.extra",
325     '%fontstyle.extra' => q"big | small | font | basefont",
326     '%fontstyle.basic' => q"tt | i | b | u
327     | s | strike ",
328     '%fontstyle' => q"%fontstyle.basic | %fontstyle.extra",
329     '%phrase.extra' => q"sub | sup",
330     '%phrase.basic' => q"em | strong | dfn | code | q |
331     samp | kbd | var | cite | abbr | acronym",
332     '%phrase' => q"%phrase.basic | %phrase.extra",
333     '%inline.forms' => q"input | select | textarea | label | button",
334     '%misc' => q"noscript | %misc.inline",
335     '%misc.inline' => q"ins | del | script",
336     '%inline' => q"a | %special | %fontstyle | %phrase | %inline.forms",
337     '%Inline' => q"#PCDATA | %inline | %misc.inline",
338     '%heading' => q"h1|h2|h3|h4|h5|h6",
339     '%lists' => q"ul | ol | dl | menu | dir",
340     '%blocktext' => q"pre | hr | blockquote | address | center",
341     '%block' => q"p | %heading | div | %lists | %blocktext | isindex |fieldset | table",
342     '%Flow' => q"#PCDATA | %block | form | %inline | %misc",
343     },
344     },
345     {
346     name => q<XHTML 1.0 SE Strict>,
347     class => {
348     '%special' => q"%special.pre | object | img ",
349     '%special.pre' => q"br | span | bdo | map",
350     '%fontstyle' => q"tt | i | b | big | small",
351     '%phrase' => q"em | strong | dfn | code | q |
352     samp | kbd | var | cite | abbr | acronym | sub | sup",
353     '%inline.forms' => q"input | select | textarea | label | button",
354     '%misc' => q"noscript | %misc.inline",
355     '%misc.inline' => q"ins | del | script",
356     '%inline' => q"a | %special | %fontstyle | %phrase | %inline.forms",
357     '%Inline' => q"#PCDATA | %inline | %misc.inline",
358     '%heading' => q"h1|h2|h3|h4|h5|h6",
359     '%lists' => q"ul | ol | dl",
360     '%blocktext' => q"pre | hr | blockquote | address",
361     '%block' => q"p | %heading | div | %lists | %blocktext | fieldset | table",
362     '%Block' => q"%block | form | %misc",
363     '%Flow' => q"#PCDATA | %block | form | %inline | %misc",
364     },
365     },
366     {
367     name => q<XHTML 1.1>,
368     class => {
369     '%Edit.class' => q"ins | del ",
370     '%Script.class' => q"script noscript",
371     '%Misc.extra' => q"",
372     '%Misc.class' => q"%Edit.class %Script.class %Misc.extra ",
373     '%InlStruct.class' => q"br span",
374     '%InlPhras.class' => q"em strong dfn code samp kbd var cite abbr acronym q",
375     '%InlPres.class' => q"tt i b big small sub sup",
376     '%I18n.class' => q"bdo",
377     '%Anchor.class' => q"a",
378     '%InlSpecial.class' => q"img map object",
379     '%InlForm.class' => q"input select textarea label button",
380     '%Inline.extra' => q"",
381     '%Ruby.class' => q"ruby",
382     '%Inline.class' => q"%InlStruct.class %InlPhras.class %InlPres.class %I18n.class %Anchor.class %InlSpecial.class %InlForm.class %Ruby.class %Inline.extra ",
383     '%InlNoRuby.class' => q"%InlStruct.class %InlPhras.class %InlPres.class %I18n.class %Anchor.class %InlSpecial.class %InlForm.class %Inline.extra ",
384     '%NoRuby.content' => q"#PCDATA %InlNoRuby.class %Misc.class ",
385     '%InlNoAnchor.class' => q"%InlStruct.class %InlPhras.class %InlPres.class %I18n.class %InlSpecial.class %InlForm.class %Ruby.class %Inline.extra ",
386     '%InlNoAnchor.mix' => q"%InlNoAnchor.class %Misc.class ",
387     '%Inline.mix' => q"%Inline.class %Misc.class ",
388     '%Heading.class' => q"h1 h2 h3 h4 h5 h6",
389     '%List.class' => q"ul ol dl",
390     '%Table.class' => q"table",
391     '%Form.class' => q"form",
392     '%Fieldset.class' => q"fieldset",
393     '%BlkStruct.class' => q"p div",
394     '%BlkPhras.class' => q"pre blockquote address",
395     '%BlkPres.class' => q"hr",
396     '%BlkSpecial.class' => q"%Table.class %Form.class %Fieldset.class ",
397     '%Block.extra' => q"",
398     '%Block.class' => q"%BlkStruct.class %BlkPhras.class %BlkPres.class %BlkSpecial.class %Block.extra ",
399     '%Block.mix' => q"%Heading.class %List.class %Block.class %Misc.class ",
400     '%Flow.mix' => q"%Heading.class %List.class %Block.class %Inline.class %Misc.class ",
401     },
402     },
403     {
404     name => q<XHTML m12n 1.0 FE/SE Abstract>,
405     class => {
406     'Heading' => q"h1 | h2 | h3 | h4 | h5 | h6",
407     'Block' => q"address | blockquote | div | p | pre | hr Form table script noscript",
408     'Inline' => q"abbr | acronym | br | cite | code | dfn | em | kbd | q | samp | span | strong | var a applet b big i small sub sup tt ins del bdo Formctrl img map object iframe script noscript",
409     'Flow' => q"Heading | Block | Inline List",
410     'List' => q"dl | ol | ul",
411     'Form' => q"form fieldset",
412     'Formctrl' => q"input | select | textarea | label | button",
413     },
414     },
415     ];
416    
417     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
418     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
419     ins del script noscript %Edit.class %Script.class %Misc.extra %misc.inline %misc %Misc.class
420     %flow %Flow %Flow.class %Flow.mix Flow/];
421     my @span;
422    
423     for (@$list) {
424     next if $argv{'no-strict'} and $_->{name} =~ /Strict|ISO-HTML|XHTML 1.1|m12n/;
425     next if $argv{'no-transitional'} and $_->{name} =~ /Transitional/;
426     next if $argv{'no-frameset'} and $_->{name} =~ /Frameset/;
427     add table => $tbl, name => $_->{name}, list => $_->{class};
428     }
429     $tbl = remove_empty_row $tbl;
430     merge_row $tbl, \@span;
431     merge_col $tbl, \@span;
432    
433     print STDOUT qq<<!DOCTYPE table SYSTEM>\n>;
434     print STDOUT serialize $tbl, \@span;
435    
436     =head1 NAME
437    
438     mkclstbl - HTML Element Type Class History Table Generator
439    
440     =head1 SYNOPSIS
441    
442     mkclstbl.pl [--no-strict] [--no-transitional] [--no-frameset] > table.html
443     mkclstbl.pl --help
444    
445     =head1 DESCRIPTION
446    
447     This script generates an HTML table that describes what element type belongs
448     what element class(es) in versions of HTML.
449    
450     =head1 OPTIONS
451    
452     This script has four arguments:
453    
454     =over 4
455    
456     =item --help
457    
458     Show help message.
459    
460     =item --no-frameset
461    
462     Omit some columns that describes Frameset DTDs.
463    
464     =item --no-strict
465    
466     Omit some columns that describes Strict DTDs, ISO-HTML, XHTML 1.1 or
467     XHTML m12n Abstract Modules.
468    
469     =item --no-transitional
470    
471     Omit some columns that describes Transitional DTDs.
472    
473     =back
474    
475     =head1 SEE ALSO
476    
477     HTML Specifications and DTDs.
478    
479     <http://suika.fam.cx/www/2004/html/>.
480    
481     =head1 LICENSE
482    
483     Copyright 2004 Wakaba <w@suika.fam.cx>
484    
485     This program is free software; you can redistribute it and/or
486     modify it under the same terms as Perl itself.
487    
488     =cut
489    
490     # $Date:$

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24