File Coverage

blib/lib/HTML/Revelation.pm
Criterion Covered Total %
statement 24 145 16.5
branch 0 36 0.0
condition 0 6 0.0
subroutine 8 16 50.0
pod 0 8 0.0
total 32 211 15.1


line stmt bran cond sub pod time code
1             package HTML::Revelation;
2              
3 1     1   20899 use strict;
  1         3  
  1         35  
4 1     1   5 use warnings;
  1         3  
  1         54  
5              
6             our @accessors = (qw/caption class2depth class_name comment css_output_file css_url empty html_output_file input_file/);
7 1     1   692 use accessors::classic qw/caption class2depth class_name comment css_output_file css_url empty html_output_file input_file/;
  1         1937  
  1         8  
8              
9 1     1   325 use File::Spec;
  1         2  
  1         30  
10 1     1   718 use HTML::Entities::Interpolate;
  1         7792  
  1         6  
11 1     1   747 use HTML::Tagset;
  1         1312  
  1         42  
12 1     1   1076 use HTML::TreeBuilder;
  1         24338  
  1         16  
13 1     1   849 use List::Cycle;
  1         643  
  1         1720  
14              
15             our @ISA = qw(Exporter);
16              
17             # Items to export into callers namespace by default. Note: do not export
18             # names by default without a very good reason. Use EXPORT_OK instead.
19             # Do not simply export all your public functions/methods/constants.
20              
21             # This allows declaration use HTML::Revelation ':all';
22             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
23             # will save memory.
24             our %EXPORT_TAGS = ( 'all' => [ qw(
25              
26             ) ] );
27              
28             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
29              
30             our @EXPORT = qw(
31              
32             );
33              
34             our $VERSION = '1.03';
35              
36             # -----------------------------------------------
37              
38             sub add_caption
39             {
40 0     0 0   my($self, $output) = @_;
41              
42 0           my(@comment);
43              
44 0           push @comment, qq|
|;
45 0           push @comment, qq||; '; '; '; '; ";
46              
47 0 0         if ($self -> comment() )
48             {
49 0           push @comment, '
Comment:' . $self -> comment() . '
50             }
51              
52 0           push @comment, '
Input file:' . $self -> input_file() . '
53 0           push @comment, '
HTML output file:' . $self -> html_output_file() . '
54 0           push @comment, '
CSS output file:' . $self -> css_output_file() . '
55 0           push @comment, '
Creator:' . __PACKAGE__ . " V $VERSION
56 0           push @comment, '
';
57 0           push @comment, '';
58 0           push @comment, qq|
|;
59              
60 0           push @$output, @comment;
61              
62             } # End of add_caption.
63              
64             # -----------------------------------------------
65              
66             sub build_css_file
67             {
68 0     0 0   my($self) = @_;
69 0           my(@color) = split(/\n/, $self -> load_colors() );
70              
71             # Discard dark colors.
72              
73 0           shift @color for 1 .. 220;
74              
75 0           my($cycle) = List::Cycle -> new({values => \@color});
76 0           my($class) = 'c0000';
77 0           my($class_name) = $self -> class_name();
78 0           my($depth) = $self -> class2depth();
79 0           my($output) = [];
80              
81 0           my($color);
82             my($padding);
83              
84 0           while ($class lt $class_name)
85             {
86 0           $class++;
87              
88 0           $color = $cycle -> next();
89 0           $padding = 4 * $$depth{$class};
90              
91 0           push @$output, <
92             .$class
93             {
94             background-color: $color;
95             border-style: solid;
96             border-width: 1px;
97             padding-left: ${padding}px;
98             padding-right: ${padding}px;
99             }
100              
101             EOS
102             }
103              
104 0           return $output;
105              
106             } # End of build_css_file.
107              
108             # -----------------------------------------------
109              
110             sub empty_tag
111             {
112 0     0 0   my($self, $tag_name) = @_;
113              
114 0   0       return ${$self -> empty()}{$tag_name} || 0;
115              
116             } # End of empty_tag.
117              
118             # -----------------------------------------------
119              
120             sub format_attributes
121             {
122 0     0 0   my($self, $node) = @_;
123 0           my(%attr) = $node -> all_attr();
124              
125 0           my(@s);
126              
127 0           push @s, map{qq|$_ = "$attr{$_}"|} grep{! /^_/} sort keys %attr;
  0            
  0            
128              
129 0   0       my($s) = join(', ', @s) || '';
130 0 0         $s = " $s" if ($s);
131              
132 0           return $s;
133              
134             } # End of format_attributes.
135              
136             # -----------------------------------------------
137              
138             sub load_colors
139             {
140 0     0 0   my($self) = @_;
141              
142 0           return <
143             000000
144             000080
145             00008B
146             0000CD
147             0000EE
148             0000FF
149             006400
150             00688B
151             008000
152             008080
153             00868B
154             008B00
155             008B45
156             008B8B
157             009ACD
158             00B2EE
159             00BFFF
160             00C5CD
161             00CD00
162             00CD66
163             00CDCD
164             00CED1
165             00E5EE
166             00EE00
167             00EE76
168             00EEEE
169             00F5FF
170             00FA9A
171             00FF00
172             00FF7F
173             00FFFF
174             030303
175             050505
176             080808
177             0A0A0A
178             0D0D0D
179             0F0F0F
180             104E8B
181             121212
182             141414
183             171717
184             1874CD
185             191970
186             1A1A1A
187             1C1C1C
188             1C86EE
189             1E90FF
190             1F1F1F
191             20B2AA
192             212121
193             228B22
194             242424
195             262626
196             27408B
197             292929
198             2B2B2B
199             2E2E2E
200             2E8B57
201             2F4F4F
202             303030
203             32814B
204             32CD32
205             333333
206             363636
207             36648B
208             383838
209             3A5FCD
210             3B3B3B
211             3CB371
212             3D3D3D
213             404040
214             40E0D0
215             4169E1
216             424242
217             436EEE
218             43CD80
219             454545
220             458B00
221             458B74
222             4682B4
223             473C8B
224             474747
225             483D8B
226             4876FF
227             48D1CC
228             4A4A4A
229             4A708B
230             4B0082
231             4D4D4D
232             4EEE94
233             4F4F4F
234             4F94CD
235             525252
236             528B8B
237             53868B
238             545454
239             548B54
240             54FF9F
241             551A8B
242             556B2F
243             575757
244             595959
245             5C5C5C
246             5CACEE
247             5D478B
248             5E5E5E
249             5F9EA0
250             607B8B
251             616161
252             636363
253             63B8FF
254             6495ED
255             666666
256             668B8B
257             66CD00
258             66CDAA
259             68228B
260             68838B
261             6959CD
262             696969
263             698B22
264             698B69
265             6A5ACD
266             6B6B6B
267             6B8E23
268             6C7B8B
269             6CA6CD
270             6E6E6E
271             6E7B8B
272             6E8B3D
273             707070
274             708090
275             737373
276             757575
277             76EE00
278             76EEC6
279             778899
280             787878
281             79CDCD
282             7A378B
283             7A67EE
284             7A7A7A
285             7A8B8B
286             7AC5CD
287             7B68EE
288             7CCD7C
289             7CFC00
290             7D26CD
291             7D7D7D
292             7E7E7E
293             7EC0EE
294             7F7F7F
295             7FFF00
296             7FFFD4
297             800000
298             800080
299             808000
300             808080
301             828282
302             836FFF
303             838B83
304             838B8B
305             8470FF
306             858585
307             878787
308             87CEEB
309             87CEFA
310             87CEFF
311             8968CD
312             8A2BE2
313             8A8A8A
314             8B0000
315             8B008B
316             8B0A50
317             8B1A1A
318             8B1C62
319             8B2252
320             8B2323
321             8B2500
322             8B3626
323             8B3A3A
324             8B3A62
325             8B3E2F
326             8B4500
327             8B4513
328             8B4726
329             8B475D
330             8B4789
331             8B4C39
332             8B5742
333             8B5A00
334             8B5A2B
335             8B5F65
336             8B636C
337             8B6508
338             8B668B
339             8B6914
340             8B6969
341             8B7355
342             8B7500
343             8B7765
344             8B795E
345             8B7B8B
346             8B7D6B
347             8B7D7B
348             8B7E66
349             8B814C
350             8B8378
351             8B8386
352             8B864E
353             8B8682
354             8B8878
355             8B8970
356             8B8989
357             8B8B00
358             8B8B7A
359             8B8B83
360             8C8C8C
361             8DB6CD
362             8DEEEE
363             8EE5EE
364             8F8F8F
365             8FBC8F
366             90EE90
367             912CEE
368             919191
369             9370DB
370             9400D3
371             949494
372             969696
373             96CDCD
374             97FFFF
375             98F5FF
376             98FB98
377             9932CC
378             999999
379             9A32CD
380             9AC0CD
381             9ACD32
382             9AFF9A
383             9B30FF
384             9BCD9B
385             9C9C9C
386             9E9E9E
387             9F79EE
388             9FB6CD
389             A020F0
390             A0522D
391             A1A1A1
392             A2B5CD
393             A2CD5A
394             A3A3A3
395             A4D3EE
396             A52A2A
397             A6A6A6
398             A8A8A8
399             A9A9A9
400             AB82FF
401             ABABAB
402             ADADAD
403             ADD8E6
404             ADFF2F
405             AEEEEE
406             AFEEEE
407             B03060
408             B0B0B0
409             B0C4DE
410             B0E0E6
411             B0E2FF
412             B22222
413             B23AEE
414             B2DFEE
415             B3B3B3
416             B3EE3A
417             B452CD
418             B4CDCD
419             B4EEB4
420             B5B5B5
421             B8860B
422             B8B8B8
423             B9D3EE
424             BA55D3
425             BABABA
426             BBFFFF
427             BC8F8F
428             BCD2EE
429             BCEE68
430             BDB76B
431             BDBDBD
432             BEBEBE
433             BF3EFF
434             BFBFBF
435             BFEFFF
436             C0C0C0
437             C0FF3E
438             C1CDC1
439             C1CDCD
440             C1FFC1
441             C2C2C2
442             C4C4C4
443             C6E2FF
444             C71585
445             C7C7C7
446             C9C9C9
447             CAE1FF
448             CAFF70
449             CCCCCC
450             CD0000
451             CD00CD
452             CD1076
453             CD2626
454             CD2990
455             CD3278
456             CD3333
457             CD3700
458             CD4F39
459             CD5555
460             CD5B45
461             CD5C5C
462             CD6090
463             CD6600
464             CD661D
465             CD6839
466             CD6889
467             CD69C9
468             CD7054
469             CD8162
470             CD8500
471             CD853F
472             CD8C95
473             CD919E
474             CD950C
475             CD96CD
476             CD9B1D
477             CD9B9B
478             CDAA7D
479             CDAD00
480             CDAF95
481             CDB38B
482             CDB5CD
483             CDB79E
484             CDB7B5
485             CDBA96
486             CDBE70
487             CDC0B0
488             CDC1C5
489             CDC5BF
490             CDC673
491             CDC8B1
492             CDC9A5
493             CDC9C9
494             CDCD00
495             CDCDB4
496             CDCDC1
497             CFCFCF
498             D02090
499             D15FEE
500             D1C166
501             D1D1D1
502             D1EEEE
503             D2691E
504             D2B48C
505             D3D3D3
506             D4D4D4
507             D6D6D6
508             D8BFD8
509             D9D9D9
510             DA70D6
511             DAA520
512             DB7093
513             DBDBDB
514             DC143C
515             DCDCDC
516             DDA0DD
517             DEB887
518             DEDEDE
519             E066FF
520             E0E0E0
521             E0EEE0
522             E0EEEE
523             E0FFFF
524             E3E3E3
525             E5E5E5
526             E6E6FA
527             E8E8E8
528             E9967A
529             EBEBEB
530             EDEDED
531             EE0000
532             EE00EE
533             EE1289
534             EE2C2C
535             EE30A7
536             EE3A8C
537             EE3B3B
538             EE4000
539             EE5C42
540             EE6363
541             EE6A50
542             EE6AA7
543             EE7600
544             EE7621
545             EE7942
546             EE799F
547             EE7AE9
548             EE8262
549             EE82EE
550             EE9572
551             EE9A00
552             EE9A49
553             EEA2AD
554             EEA9B8
555             EEAD0E
556             EEAEEE
557             EEB422
558             EEB4B4
559             EEC591
560             EEC900
561             EECBAD
562             EECFA1
563             EED2EE
564             EED5B7
565             EED5D2
566             EED8AE
567             EEDC82
568             EEDD82
569             EEDFCC
570             EEE0E5
571             EEE5DE
572             EEE685
573             EEE8AA
574             EEE8CD
575             EEE9BF
576             EEE9E9
577             EEEE00
578             EEEED1
579             EEEEE0
580             F08080
581             F0E68C
582             F0F0F0
583             F0F8FF
584             F0FFF0
585             F0FFFF
586             F2F2F2
587             F4A460
588             F5DEB3
589             F5F5DC
590             F5F5F5
591             F5FFFA
592             F7F7F7
593             F8F8FF
594             FA8072
595             FAEBD7
596             FAF0E6
597             FAFAD2
598             FAFAFA
599             FCFCFC
600             FDF5E6
601             FF0000
602             FF00FF
603             FF1493
604             FF3030
605             FF34B3
606             FF3E96
607             FF4040
608             FF4500
609             FF6347
610             FF69B4
611             FF6A6A
612             FF6EB4
613             FF7256
614             FF7F00
615             FF7F24
616             FF7F50
617             FF8247
618             FF82AB
619             FF83FA
620             FF8C00
621             FF8C69
622             FFA07A
623             FFA500
624             FFA54F
625             FFAEB9
626             FFB5C5
627             FFB6C1
628             FFB90F
629             FFBBFF
630             FFC0CB
631             FFC125
632             FFC1C1
633             FFD39B
634             FFD700
635             FFDAB9
636             FFDEAD
637             FFE1FF
638             FFE4B5
639             FFE4C4
640             FFE4E1
641             FFE7BA
642             FFEBCD
643             FFEC8B
644             FFEFD5
645             FFEFDB
646             FFF0F5
647             FFF5EE
648             FFF68F
649             FFF8DC
650             FFFACD
651             FFFAF0
652             FFFAFA
653             FFFF00
654             FFFFE0
655             FFFFF0
656             FFFFFF
657             EOS
658              
659             } # End of load_colors.
660              
661             # -----------------------------------------------
662              
663             sub new
664             {
665 0     0 0   my($class, %arg) = @_;
666 0           my($self) = bless({}, $class);
667              
668             # Set defaults.
669              
670 0           $self -> caption(0);
671 0           $self -> class2depth({});
672 0           $self -> class_name('c0000');
673 0           $self -> comment('');
674 0           $self -> css_output_file('');
675 0           $self -> css_url('');
676 0           $self -> empty
677             ({
678             area => 1,
679             base => 1,
680             basefont => 1,
681             br => 1,
682             col => 1,
683             embed => 1,
684             frame => 1,
685             hr => 1,
686             img => 1,
687             input => 1,
688             isindex => 1,
689             link => 1,
690             meta => 1,
691             param => 1,
692             wbr => 1,
693             });
694 0           $self -> html_output_file('');
695 0           $self -> input_file('');
696              
697             # Process user options.
698              
699 0           my($attr_name);
700              
701 0           for $attr_name (@accessors)
702             {
703 0 0         if (exists($arg{$attr_name}) )
704             {
705 0           $self -> $attr_name($arg{$attr_name});
706             }
707             }
708              
709 0 0         if (! $self -> css_output_file() )
710             {
711 0           die 'CSS output file not specifed';
712             }
713              
714 0 0         if (! $self -> css_url() )
715             {
716 0           die 'CSS URL not specifed';
717             }
718              
719 0 0         if (! $self -> html_output_file() )
720             {
721 0           die 'HTML output file not specifed';
722             }
723              
724 0 0         if (! -f $self -> input_file() )
725             {
726 0           die 'Cannot find input file: ' . $self -> input_file();
727             }
728              
729 0           $$self{'_empty'} =
730             {
731             area => 1,
732             base => 1,
733             basefont => 1,
734             br => 1,
735             col => 1,
736             embed => 1,
737             frame => 1,
738             hr => 1,
739             img => 1,
740             input => 1,
741             isindex => 1,
742             link => 1,
743             meta => 1,
744             param => 1,
745             wbr => 1,
746             };
747              
748 0           return $self;
749              
750             } # End of new.
751              
752             # -----------------------------------------------
753              
754             sub process
755             {
756 0     0 0   my($self, $css_url, $depth, $node, $output) = @_;
757              
758 0           $depth++;
759              
760             # If ref $node is true, this node has children, so we're going to recurse.
761              
762 0 0         if (ref $node)
763             {
764 0           my($tag) = lc $node -> tag();
765 0           my($empty_tag) = $self -> empty_tag($tag);
766              
767 0           my($content);
768              
769             # If the tag can appear in the body, apply makeup aka markup.
770              
771 0 0         if ($HTML::Tagset::isBodyElement{$tag})
772             {
773             # Fabricate a CSS class name for this node,
774             # and stash it away for when we generate the CSS file.
775              
776 0           my($class_name) = $self -> class_name();
777              
778 0           $class_name++;
779              
780 0           $self -> class_name($class_name);
781              
782 0           my($hash_ref) = $self -> class2depth();
783 0           $$hash_ref{$class_name} = $depth;
784              
785 0           $self -> class2depth($hash_ref);
786              
787             # Start a div for this node.
788              
789 0           my($s) = $self -> format_attributes($node);
790              
791 0 0         if ($empty_tag)
792             {
793 0           $s .= ' /';
794             }
795              
796 0           push @$output, qq|
$Entitize{"<$tag$s>"}|;
797              
798             # Process this node's children.
799              
800 0           for $content ($node -> content_list() )
801             {
802 0           $self -> process($css_url, $depth, $content, $output);
803             }
804              
805 0           $s = '';
806              
807 0 0         if (! $empty_tag)
808             {
809 0           $s = qq|$Entitize{""}$s|;
810             }
811              
812 0           push @$output, $s;
813             }
814             else
815             {
816             # It's the head-type tag, so just output it. This includes the real body tag.
817              
818 0 0         push @$output, "<$tag" . ($empty_tag ? ' /' : '') . '>';
819              
820             # Add commentry, if desired, just after we output the real body tag.
821              
822 0 0         if ($tag eq 'body')
823             {
824 0 0         if ($self -> caption() )
825             {
826 0           $self -> add_caption($output);
827             }
828              
829             # Output a fake (i.e. visible) body tag.
830              
831 0           my($s) = $self -> format_attributes($node);
832              
833 0           push @$output, $Entitize{""};
834             }
835              
836             # Process this node's children.
837              
838 0           for $content ($node -> content_list() )
839             {
840 0           $self -> process($css_url, $depth, $content, $output);
841             }
842              
843             # Output the CSS link just before we output .
844              
845 0 0         if ($tag eq 'head')
846             {
847 0           push @$output, qq||;
848             }
849              
850 0 0         if (! $empty_tag)
851             {
852 0           push @$output, "";
853             }
854             }
855             }
856             # else
857             # {
858             # # This would include the input text in the output.
859             #
860             # push @$output, $node;
861             # }
862              
863             } # End of process.
864              
865             # -----------------------------------------------
866              
867             sub run
868             {
869 0     0 0   my($self) = @_;
870 0           my($root) = HTML::TreeBuilder -> new();
871 0           my($input_file) = $self -> input_file();
872 0   0       my($result) = $root -> parse_file($input_file) || die "Can't parse: $input_file";
873 0           my($depth) = 0;
874 0           my($output) = [];
875              
876             # Build the HTML output.
877              
878 0           $self -> process($self -> css_url(), $depth, $root, $output);
879 0           $root -> delete();
880              
881 0           push @$output, $Entitize{''};
882              
883             # Write the HMTL file.
884              
885 0           my($html_output_file) = $self -> html_output_file();
886              
887 0 0         open(OUT, "> $html_output_file") || die "Can't open(> $html_output_file): $!";
888 0           print OUT join("\n", @$output), "\n";
889 0           close OUT;
890              
891             # Write the CSS file.
892              
893 0           $output = $self -> build_css_file();
894 0           my($css_output_file) = $self -> css_output_file();
895              
896 0 0         open(OUT, "> $css_output_file") || die "Can't open(> $css_output_file): $!";
897 0           print OUT map{"$_\n"} @$output;
  0            
898 0           close OUT;
899              
900             } # End of run.
901              
902             # -----------------------------------------------
903              
904             1;
905              
906             =pod
907              
908             =head1 NAME
909              
910             HTML::Revelation - Reveal HTML document structure in a myriad of colors
911              
912             =head1 Synopsis
913              
914             #!/usr/bin/perl
915              
916             use strict;
917             use warnings;
918              
919             use HTML::Revelation;
920              
921             # -------------------
922              
923             my($reveal) = HTML::Revelation -> new
924             (
925             caption => 1,
926             comment => "DBIx::Admin::CreateTable's POD converted to HTML with my pod2html.pl",
927             css_output_file => 'CreateTable.css',
928             css_url => '/',
929             html_output_file => 'CreateTable.html',
930             input_file => 'misc/CreateTable.html',
931             );
932              
933             $reveal -> run();
934              
935             Sample output:
936              
937             http://savage.net.au/Perl-modules/html/CreateTable.html
938              
939             =head1 Description
940              
941             C is a pure Perl module.
942              
943             =head1 Constructor and initialization
944              
945             C returns a C object.
946              
947             This is the class's contructor.
948              
949             You must pass a hash to C.
950              
951             Options:
952              
953             =over 4
954              
955             =item caption => 0 | 1
956              
957             Use this key to display or suppress a caption (a table of information) at the start of the HTML output file.
958              
959             The default is 0.
960              
961             This key is optional.
962              
963             =item comment => $s
964              
965             Use this key to add a comment to the caption (if displayed).
966              
967             The default is '' (the empty string).
968              
969             This key is optional.
970              
971             =item css_output_file => $s
972              
973             Use this key to specify the name of the CSS output file.
974              
975             The default is '' (the empty string).
976              
977             This key is mandatory.
978              
979             =item css_url => $s
980              
981             Use this key to specify the URL of the CSS output file.
982              
983             This URL is written into the HTML output file.
984              
985             The default is '' (the empty string).
986              
987             This key is mandatory.
988              
989             =item html_output_file => $s
990              
991             Use this key to specify the name of the HTML output file.
992              
993             The default is '' (the empty string).
994              
995             This key is mandatory.
996              
997             =item input_file => $s
998              
999             Use this key to specify the name of the HTML input file.
1000              
1001             The default is '' (the empty string).
1002              
1003             This key is mandatory.
1004              
1005             =back
1006              
1007             =head1 Method: add_caption()
1008              
1009             Factor out the code which formats the caption.
1010              
1011             =head1 Method: build_css_file()
1012              
1013             Factor out the code which build the body of the CSS output file.
1014              
1015             =head1 Method: load_colors()
1016              
1017             Factor out the code which stores the data defining the available colors.
1018              
1019             =head1 Method: run()
1020              
1021             As shown in the synopsis, you must call C on your C object in order to
1022             generate the output files.
1023              
1024             =head1 FAQ
1025              
1026             =over 4
1027              
1028             =item Where did the colors come from?
1029              
1030             From the Image::Magick web site. I extracted them from a web page there using the
1031             amazing HTML::TreeBuilder module. See scripts/extract.colors.pl.
1032              
1033             =item Why do you discard the first 220 colors?
1034              
1035             Because they are too dark for my liking.
1036              
1037             =item Why does the caption use CSS class c0003?
1038              
1039             I like that color - it's nice and restful. I seriously considered using c0201.
1040              
1041             =item I want to know which CSS class produces which color.
1042              
1043             Patch line 743 to put ' $class_name' just inside the '|' at the end of the line.
1044              
1045             =back
1046              
1047             =head1 Modules Used
1048              
1049             =over 4
1050              
1051             =item accessors::classic
1052              
1053             =item File::Spec
1054              
1055             =item HTML::Entities::Interpolate
1056              
1057             =item HTML::Tagset
1058              
1059             =item HTML::TreeBuilder
1060              
1061             =item List::Cycle
1062              
1063             =back
1064              
1065             =head1 Author
1066              
1067             C was written by Ron Savage Iron@savage.net.auE> in 2008.
1068              
1069             Home page: http://savage.net.au/index.html
1070              
1071             =head1 Copyright
1072              
1073             Australian copyright (c) 2008, Ron Savage.
1074             All Programs of mine are 'OSI Certified Open Source Software';
1075             you can redistribute them and/or modify them under the terms of
1076             the Artistic or the GPL licences, copies of which is available at:
1077             http://www.opensource.org/licenses/index.html
1078              
1079             =cut