File Coverage

blib/lib/Text/XHTML.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Text::XHTML;
2 1     1   26777 use strict;
  1         2  
  1         31  
3 1     1   5 use warnings;
  1         1  
  1         24  
4 1     1   364 use Types;
  0            
  0            
5             use Text::XML qw(:all);
6             use Carp;
7             use Exporter;
8             use base qw/Exporter/;
9              
10             our $VERSION = '0.1';
11              
12             our %EXPORT_TAGS = (
13             elements => [qw(abbr acronym address anchor area bdo big blockquote body bold
14             button br caption cite col colgroup ddef define del dlist dterm
15             emphasize fieldset form h1 h2 h3 h4 h5 h6 head hr image input
16             ins italics keyboard label legend li meta noscript object olist
17             optgroup option paragraph param pre quote sample script select
18             small strong thestyle subscript superscript table tbody td
19             textarea tfoot th thead thebase code div html span thetitle
20             trow tt ulist variable)],
21             attributes => [qw(action align alt altcode archive base border bordercolor
22             cellpadding checked codebase cols colspan content coords
23             disabled enctype height href httpequiv identifier ismap lang
24             maxlength method multiple name nohref rel rev rows rowspan
25             rules selected shape size src class afor style type title
26             usemap valign value width)]
27             );
28              
29             our @EXPORT_OK = ( qw(text comment attr cdata)
30             , @{$EXPORT_TAGS{elements}}
31             , @{$EXPORT_TAGS{attributes}}
32             );
33              
34             $EXPORT_TAGS{all} = \@EXPORT_OK;
35              
36             our $CHECKS = 1;
37              
38             our %CTXT =
39             ( 'Text::XHTML::CtxText'
40             => { _text => 1 }
41             , 'Text::XHTML::CtxHead'
42             => {map {$_=>1} qw(base link meta title stype script)}
43             , 'Text::XHTML::CtxOption'
44             => {map {$_=>1} qw(option optgroup)}
45             , 'Text::XHTML::CtxDList'
46             => {map {$_=>1} qw(dt dd)}
47             , 'Text::XHTML::CtxList'
48             => { li => 1 }
49             , 'Text::XHTML::CtxTable'
50             => {map {$_=>1} qw(caption col colgroup thead tfoot tbody tr)}
51             , 'Text::XHTML::CtxBlock'
52             => {map {$_=>1} qw(ins del noscript address blockquote div dl fieldset
53             form h1 h2 h3 h4 h5 h6 hr ol p pre table ul script)}
54             , 'Text::XHTML::CtxForm'
55             => {map {$_=>1} qw(ins del noscript address blockquote div dl fieldset
56             form h1 h2 h3 h4 h5 h6 hr ol p pre table ul script
57             fieldset)}
58             , 'Text::XHTML::CtxMap'
59             => {map {$_=>1} qw(ins del noscript address blockquote div dl fieldset
60             form h1 h2 h3 h4 h5 h6 hr ol p pre table ul script
61             map)}
62             , 'Text::XHTML::CtxInline'
63             => {map {$_=>1} qw(ins del noscript abbr acronym a bdo big b button
64             br cite dfn em img input i kbd label legend object
65             q sample select small strong sub sup
66             textarea code span tt var _text)}
67             , 'Text::XHTML::CtxAnchor'
68             => {map {$_=>1} qw(ins del noscript abbr acronym bdo big b button
69             br cite dfn em img input i kbd label legend object
70             q sample select small strong sub sup
71             textarea code span tt var _text)}
72             , 'Text::XHTML::CtxInlineBlock'
73             => {map {$_=>1} qw(ins del noscript address blockquote div dl fieldset
74             form h1 h2 h3 h4 h5 h6 hr ol p pre table ul script
75             abbr acronym a bdo big b button
76             br cite dfn em img input i kbd label legend object
77             q sample select small strong sub sup
78             textarea code span tt var _text)}
79             , 'Text::XHTML::CtxFieldSet'
80             => {map {$_=>1} qw(ins del noscript address blockquote div dl fieldset
81             form h1 h2 h3 h4 h5 h6 hr ol p pre table ul script
82             abbr acronym a bdo big b button
83             br cite dfn em img input i kbd label legend object
84             q sample select small strong sub sup
85             textarea code span tt var _text legend)}
86             , 'Text::XHTML::CtxObject'
87             => {map {$_=>1} qw(ins del noscript address blockquote div dl fieldset
88             form h1 h2 h3 h4 h5 h6 hr ol p pre table ul script
89             abbr acronym a bdo big b button
90             br cite dfn em img input i kbd label legend object
91             q sample select small strong sub sup
92             textarea code span tt var _text object)}
93             , 'Text::XHTML::CtxButton'
94             => {map {$_=>1} qw(ins del noscript address blockquote div dl
95             h1 h2 h3 h4 h5 h6 hr ol p pre table ul script
96             abbr acronym a bdo big b
97             br cite dfn em img i kbd legend object
98             q sample small strong sub sup
99             code span tt var _text)}
100             );
101              
102             newtype Text::XHTML::HTML;
103              
104             # Element context
105             newtype Text::XHTML::CtxHead;
106             newtype Text::XHTML::CtxBlock;
107             newtype Text::XHTML::CtxInline;
108             newtype Text::XHTML::CtxInlineBlock;
109             newtype Text::XHTML::CtxOption;
110             newtype Text::XHTML::CtxDList;
111             newtype Text::XHTML::CtxList;
112             newtype Text::XHTML::CtxForm;
113             newtype Text::XHTML::CtxFieldSet;
114             newtype Text::XHTML::CtxTable;
115             newtype Text::XHTML::CtxMap;
116             newtype Text::XHTML::CtxObject;
117             newtype Text::XHTML::CtxAnchor;
118             newtype Text::XHTML::CtxButton;
119             newtype Text::XHTML::CtxText;
120              
121             uniontype Text::XHTML::Inline, qw(Text::XHTML::CtxInline
122             Text::XHTML::CtxText
123             Text::XHTML::CtxAnchor);
124              
125             instance Text::Pretty::Print, Text::XHTML::HTML,
126             pretty => sub { my( $doc, %opts ) = @_
127             ; ($doc) = @{$doc}
128             ; $opts{prolog} = 1
129             ; $opts{doctype} =
130             [ q{html}
131             , q{PUBLIC}
132             , q{"-//W3C//DTD XHTML 1.0 Strict//EN"}
133             , q{"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"}
134             ]
135             ; $doc->pretty(%opts) };
136              
137             sub el (*$$) { my( $e, $c, $ctx ) = @_
138             ; my( $a, $o )
139             ; $CHECKS
140             ? do{ assertlisttype Text::XML::XML, $c
141             ; ( $a, $o ) = separatetype Text::XML::Attribute, $c
142             ; for my $b (@$o) { $b->isa('Text::XML::Element')
143             ? exists $CTXT{ref($ctx)}->{$b->[0]->[0]}
144             ? next
145             : confess q{Element <}.$b->[0]->[0]
146             .q{> cannot be in a }.ref($ctx).' context'
147             : $b->isa('Text::XML::Text')
148             ? exists $CTXT{ref($ctx)}->{'_text'}
149             ? next
150             : confess q{Text cannot be in a }.ref($ctx).' context'
151             : next
152             }
153             }
154             : do {( $a, $o ) = separatetype Text::XML::Attribute, $c}
155             ; $ctx->isa('Text::XHTML::Inline')
156             ? ielem $e, $a, $o
157             : elem $e, $a, $o
158             }
159              
160             sub ele (*;$) { my( $e, $c ) = @_
161             ; assertlisttype Text::XML::Attribute, $c if $CHECKS
162             ; elem $e, $c, []
163             }
164              
165             # root element
166             sub html ($$$) { my($a,$h,$b)=@_
167             ; assertlisttype Text::XML::Attribute, $a if $CHECKS
168             ; confess 'No Head element' unless $h->[0]->[0] eq 'head'
169             ; confess 'No Body element' unless $b->[0]->[0] eq 'body'
170             ; unshift @$a, attr xmlns => 'http://www.w3.org/1999/xhtml'
171             ; HTML(elem html, $a, [$h,$b]) }
172              
173             # root children elements
174             sub head ($) { el head, shift, CtxHead() }
175             sub body ($) { el body, shift, CtxBlock() }
176              
177             ###############################################################################
178             # header elements
179             # takes a string
180             sub thebase ($) { elem base, [attr href => shift], [] }
181             # takes an attribute listref
182             sub thelink ($) { ele 'link', shift }
183             # takes an attribute listref
184             sub meta ($) { ele meta, shift }
185             # takes an attribute listref, element can have 'lang' and 'dir' attributes.
186             sub thetitle ($) { el title, shift, CtxText() }
187             sub thestyle ($) { el style, shift, CtxText() }
188             sub script ($) { el script, shift, CtxText() }
189              
190             ###############################################################################
191             # block and inline elements
192             sub del ($) { el del, shift, CtxInlineBlock() }
193             sub ins ($) { el ins, shift, CtxInlineBlock() }
194             sub noscript ($) { el noscript, shift, CtxBlock() }
195              
196             ###############################################################################
197             # block elements
198             sub address ($) { el address, shift, CtxInline() }
199             sub blockquote ($) { el blockquote, shift, CtxBlock() }
200             sub div ($) { el div, shift, CtxInlineBlock() }
201             sub dlist ($) { el dl, shift, CtxDList() }
202             sub fieldset ($) { el fieldset, shift, CtxFieldSet() }
203             sub form ($) { el form, shift, CtxForm() }
204             sub h1 ($) { el h1, shift, CtxInline() }
205             sub h2 ($) { el h2, shift, CtxInline() }
206             sub h3 ($) { el h3, shift, CtxInline() }
207             sub h4 ($) { el h4, shift, CtxInline() }
208             sub h5 ($) { el h5, shift, CtxInline() }
209             sub h6 ($) { el h6, shift, CtxInline() }
210             sub hr (;$) { ele hr, shift }
211             sub olist ($) { el ol, shift, CtxList() }
212             sub paragraph ($) { el p, shift, CtxInline() }
213             sub pre ($) { el pre, shift, CtxInline() } # care
214             sub table ($) { el table, shift, CtxTable() } # care
215             sub ulist ($) { el ul, shift, CtxList() }
216              
217             ###############################################################################
218             # inline elements
219             sub abbr ($) { el abbr, shift, CtxInline() }
220             sub acronym ($) { el acronym, shift, CtxInline() }
221             sub anchor ($) { el a, shift, CtxAnchor() } # care
222             sub bdo ($) { el bdo, shift, CtxInline() }
223             sub big ($) { el big, shift, CtxInline() }
224             sub bold ($) { el b, shift, CtxInline() }
225             sub button ($) { el button, shift, CtxButton() }
226             sub br (;$) { ele br, shift }
227             sub cite ($) { el cite, shift, CtxInline() }
228             sub code ($) { el code, shift, CtxInline() }
229             sub define ($) { el dfn, shift, CtxInline() }
230             sub emphasize ($) { el em, shift, CtxInline() }
231             sub image ($) { ele img, shift }
232             sub input ($) { ele input, shift }
233             sub italics ($) { el i, shift, CtxInline() }
234             sub keyboard ($) { el kbd, shift, CtxInline() }
235             sub label ($) { el label, shift, CtxInline() }
236             sub object ($) { el object, shift, CtxObject() }
237             sub quote ($) { el 'q', shift, CtxInline() }
238             sub sample ($) { el sample, shift, CtxInline() }
239             sub select ($) { el 'select', shift, CtxOption() }
240             sub small ($) { el small, shift, CtxInline() }
241             sub strong ($) { el strong, shift, CtxInline() }
242             sub subscript ($) { el 'sub', shift, CtxInline() }
243             sub superscript ($) { el sup, shift, CtxInline() }
244             sub textarea ($) { el textarea, shift, CtxText() }
245             sub themap ($) { el 'map', shift, CtxMap() }
246             sub span ($) { el span, shift, CtxInline() }
247             sub tt ($) { el tt, shift, CtxInline() }
248             sub variable ($) { el var, shift, CtxInline() }
249              
250             ###############################################################################
251             # table elements
252             sub caption ($) { el caption, shift, CtxInline() }
253             sub col ($) { el col, shift, CtxInline() }
254             sub colgroup ($) { el colgroup, shift, CtxInline() }
255             sub tbody ($) { el tbody, shift, CtxInline() }
256             sub td ($) { el td, shift, CtxInline() }
257             sub tfoot ($) { el tfoot, shift, CtxInline() }
258             sub th ($) { el th, shift, CtxInline() }
259             sub thead ($) { el thead, shift, CtxInline() }
260             sub trow ($) { el 'tr', shift, CtxInline() }
261              
262             ###############################################################################
263             # list elements
264             sub li ($) { el li, shift, CtxInlineBlock() }
265             sub dterm ($) { el dt, shift, CtxInline() }
266             sub ddef ($) { el dd, shift, CtxInlineBlock() }
267              
268             ###############################################################################
269             # form menu options elements
270             sub optgroup ($) { el optgroup, shift, CtxInline() }
271             sub option ($) { el option, shift, CtxInline() }
272              
273             ###############################################################################
274             # other elements
275             sub area ($) { ele area, shift }
276             sub legend ($) { el legend, shift, CtxInline() }
277             sub param ($) { ele param, shift }
278              
279             ###############################################################################
280             # attributes
281             sub action ($) { attr action => shift }
282             sub align ($) { attr align => shift }
283             sub alt ($) { attr alt => shift }
284             sub altcode ($) { attr altcode => shift }
285             sub archive ($) { attr archive => shift }
286             sub base ($) { attr base => shift }
287             sub border ($) { attr border => shift }
288             sub bordercolor ($) { attr bordercolor => shift }
289             sub cellpadding ($) { attr cellpadding => shift }
290             sub checked () { attr checked => 'true'}
291             sub codebase ($) { attr codebase => shift }
292             sub cols ($) { attr cols => shift }
293             sub colspan ($) { attr colspan => shift }
294             sub content ($) { attr content => shift }
295             sub coords ($) { attr coords => shift }
296             sub disabled () { attr disabled => 'true'}
297             sub enctype ($) { attr enctype => shift }
298             sub height ($) { attr height => shift }
299             sub href ($) { attr href => shift }
300             sub httpequiv ($) { attr 'http-equiv' => shift }
301             sub identifier ($) { attr id => shift }
302             sub ismap () { attr action => 'true'}
303             sub lang ($) { my $l=shift; attr(lang=>$l), attr('xml:lang',$l) }
304             sub maxlength ($) { attr maxlength => shift }
305             sub method ($) { attr method => shift }
306             sub multiple () { attr multiple => 'true'}
307             sub name ($) { attr name => shift }
308             sub nohref () { attr nohref => 'true'}
309             sub rel ($) { attr rel => shift }
310             sub rev ($) { attr rev => shift }
311             sub rows ($) { attr rows => shift }
312             sub rowspan ($) { attr rowspan => shift }
313             sub rules ($) { attr rules => shift }
314             sub selected () { attr selected => 'true'}
315             sub shape ($) { attr shape => shift }
316             sub size ($) { attr size => shift }
317             sub src ($) { attr src => shift }
318             sub class ($) { attr class => shift }
319             sub afor ($) { attr 'for' => shift }
320             sub style ($) { attr style => shift }
321             sub type ($) { attr type => shift }
322             sub title ($) { attr title => shift }
323             sub usemap ($) { attr usemap => shift }
324             sub valign ($) { attr valign => shift }
325             sub value ($) { attr value => shift }
326             sub width ($) { attr width => shift }
327              
328             1;
329              
330             __END__