1#!/usr/bin/perl -w
2
3# t/xhtml01.t - check basic output from Pod::Simple::XHTML
4
5BEGIN {
6    chdir 't' if -d 't';
7}
8
9use strict;
10use lib '../lib';
11use Test::More tests => 61;
12#use Test::More 'no_plan';
13
14use_ok('Pod::Simple::XHTML') or exit;
15
16my $parser = Pod::Simple::XHTML->new ();
17isa_ok ($parser, 'Pod::Simple::XHTML');
18
19my $results;
20
21my $PERLDOC = "http://search.cpan.org/perldoc";
22my $MANURL = "http://man.he.net/man";
23
24initialize($parser, $results);
25$parser->parse_string_document( "=head1 Poit!" );
26is($results, qq{<h1 id="Poit">Poit!</h1>\n\n}, "head1 level output");
27
28initialize($parser, $results);
29$parser->parse_string_document( "=head2 Yada Yada Operator
30X<...> X<... operator> X<yada yada operator>" );
31is($results, qq{<h2 id="Yada-Yada-Operator">Yada Yada Operator   </h2>\n\n}, "head ID with X<>");
32
33initialize($parser, $results);
34$parser->parse_string_document( "=head2 Platforms with no supporting programmers:");
35is($results, qq{<h2 id="Platforms-with-no-supporting-programmers">Platforms with no supporting programmers:</h2>\n\n}, "head ID ending in colon");
36
37initialize($parser, $results);
38$parser->html_h_level(2);
39$parser->parse_string_document( "=head1 Poit!" );
40is($results, qq{<h2 id="Poit">Poit!</h2>\n\n}, "head1 level output h_level 2");
41
42initialize($parser, $results);
43$parser->parse_string_document( "=head2 I think so Brain." );
44is($results, qq{<h2 id="I-think-so-Brain">I think so Brain.</h2>\n\n}, "head2 level output");
45
46initialize($parser, $results);
47$parser->parse_string_document( "=head3 I say, Brain..." );
48is($results, qq{<h3 id="I-say-Brain">I say, Brain...</h3>\n\n}, "head3 level output");
49
50initialize($parser, $results);
51$parser->parse_string_document( "=head4 Zort & Zog!" );
52is($results, qq{<h4 id="Zort-Zog">Zort &amp; Zog!</h4>\n\n}, "head4 level output");
53
54sub x ($;&) {
55  my $code = $_[1];
56  Pod::Simple::XHTML->_out(
57  sub { $code->($_[0]) if $code },
58  "=pod\n\n$_[0]",
59) }
60
61like(
62  x("=head1 Header\n\n=for html <div>RAW<span>!</span></div>\n\nDone."),
63  qr/.+<\/h1>\s+<div>RAW<span>!<\/span><\/div>\s+.*/sm,
64  "heading building"
65) or exit;
66
67initialize($parser, $results);
68$parser->parse_string_document(<<'EOPOD');
69=pod
70
71Gee, Brain, what do you want to do tonight?
72EOPOD
73
74is($results, <<'EOHTML', "simple paragraph");
75<p>Gee, Brain, what do you want to do tonight?</p>
76
77EOHTML
78
79
80initialize($parser, $results);
81$parser->parse_string_document(<<'EOPOD');
82=pod
83
84B: Now, Pinky, if by any chance you are captured during this mission,
85remember you are Gunther Heindriksen from Appenzell. You moved to
86Grindelwald to drive the cog train to Murren. Can you repeat that?
87
88P: Mmmm, no, Brain, dont think I can.
89EOPOD
90
91is($results, <<'EOHTML', "multiple paragraphs");
92<p>B: Now, Pinky, if by any chance you are captured during this mission, remember you are Gunther Heindriksen from Appenzell. You moved to Grindelwald to drive the cog train to Murren. Can you repeat that?</p>
93
94<p>P: Mmmm, no, Brain, dont think I can.</p>
95
96EOHTML
97
98initialize($parser, $results);
99$parser->parse_string_document(<<'EOPOD');
100=over
101
102=item *
103
104P: Gee, Brain, what do you want to do tonight?
105
106=item *
107
108B: The same thing we do every night, Pinky. Try to take over the world!
109
110=back
111
112EOPOD
113
114is($results, <<'EOHTML', "simple bulleted list");
115<ul>
116
117<li><p>P: Gee, Brain, what do you want to do tonight?</p>
118
119</li>
120<li><p>B: The same thing we do every night, Pinky. Try to take over the world!</p>
121
122</li>
123</ul>
124
125EOHTML
126
127
128initialize($parser, $results);
129$parser->parse_string_document(<<'EOPOD');
130=over
131
132=item *
133
134P: Gee, Brain, what do you want to do tonight?
135
136=item *
137
138B: The same thing we do every night, Pinky. Try to take over the world!
139
140=over
141
142=item *
143
144Take over world
145
146=item *
147
148Do laundry
149
150=back
151
152=back
153
154EOPOD
155
156is($results, <<'EOHTML', "nested bulleted list");
157<ul>
158
159<li><p>P: Gee, Brain, what do you want to do tonight?</p>
160
161</li>
162<li><p>B: The same thing we do every night, Pinky. Try to take over the world!</p>
163
164<ul>
165
166<li><p>Take over world</p>
167
168</li>
169<li><p>Do laundry</p>
170
171</li>
172</ul>
173
174</li>
175</ul>
176
177EOHTML
178
179
180
181initialize($parser, $results);
182$parser->parse_string_document(<<'EOPOD');
183=over
184
185=item 1
186
187P: Gee, Brain, what do you want to do tonight?
188
189=item 2
190
191B: The same thing we do every night, Pinky. Try to take over the world!
192
193=back
194
195EOPOD
196
197is($results, <<'EOHTML', "numbered list");
198<ol>
199
200<li><p>P: Gee, Brain, what do you want to do tonight?</p>
201
202</li>
203<li><p>B: The same thing we do every night, Pinky. Try to take over the world!</p>
204
205</li>
206</ol>
207
208EOHTML
209
210
211initialize($parser, $results);
212$parser->parse_string_document(<<'EOPOD');
213=over
214
215=item 1
216
217P: Gee, Brain, what do you want to do tonight?
218
219=item 2
220
221B: The same thing we do every night, Pinky. Try to take over the world!
222
223=over
224
225=item 1
226
227Take over world
228
229=item 2
230
231Do laundry
232
233=back
234
235=back
236
237EOPOD
238
239is($results, <<'EOHTML', "nested numbered list");
240<ol>
241
242<li><p>P: Gee, Brain, what do you want to do tonight?</p>
243
244</li>
245<li><p>B: The same thing we do every night, Pinky. Try to take over the world!</p>
246
247<ol>
248
249<li><p>Take over world</p>
250
251</li>
252<li><p>Do laundry</p>
253
254</li>
255</ol>
256
257</li>
258</ol>
259
260EOHTML
261
262
263initialize($parser, $results);
264$parser->parse_string_document(<<'EOPOD');
265=over
266
267=item Pinky
268
269Gee, Brain, what do you want to do tonight?
270
271=item Brain
272
273The same thing we do every night, Pinky. Try to take over the world!
274
275=back
276
277EOPOD
278
279is($results, <<'EOHTML', "list with text headings");
280<dl>
281
282<dt>Pinky</dt>
283<dd>
284
285<p>Gee, Brain, what do you want to do tonight?</p>
286
287</dd>
288<dt>Brain</dt>
289<dd>
290
291<p>The same thing we do every night, Pinky. Try to take over the world!</p>
292
293</dd>
294</dl>
295
296EOHTML
297
298initialize($parser, $results);
299$parser->parse_string_document(<<'EOPOD');
300=over
301
302=item * Pinky
303
304Gee, Brain, what do you want to do tonight?
305
306=item * Brain
307
308The same thing we do every night, Pinky. Try to take over the world!
309
310=back
311
312EOPOD
313
314is($results, <<'EOHTML', "list with bullet and text headings");
315<ul>
316
317<li><p>Pinky</p>
318
319<p>Gee, Brain, what do you want to do tonight?</p>
320
321</li>
322<li><p>Brain</p>
323
324<p>The same thing we do every night, Pinky. Try to take over the world!</p>
325
326</li>
327</ul>
328
329EOHTML
330
331initialize($parser, $results);
332$parser->parse_string_document(<<'EOPOD');
333=over
334
335=item * Brain <brain@binkyandthebrain.com>
336
337=item * Pinky <pinky@binkyandthebrain.com>
338
339=back
340
341EOPOD
342
343is($results, <<'EOHTML', "bulleted author list");
344<ul>
345
346<li><p>Brain &lt;brain@binkyandthebrain.com&gt;</p>
347
348</li>
349<li><p>Pinky &lt;pinky@binkyandthebrain.com&gt;</p>
350
351</li>
352</ul>
353
354EOHTML
355
356initialize($parser, $results);
357$parser->parse_string_document(<<'EOPOD');
358=over
359
360=item Pinky
361
362=over
363
364=item World Domination
365
366=back
367
368=item Brain
369
370=back
371
372EOPOD
373
374is($results, <<'EOHTML', 'nested lists');
375<dl>
376
377<dt>Pinky</dt>
378<dd>
379
380<dl>
381
382<dt>World Domination</dt>
383<dd>
384
385</dd>
386</dl>
387
388</dd>
389<dt>Brain</dt>
390<dd>
391
392</dd>
393</dl>
394
395EOHTML
396
397initialize($parser, $results);
398$parser->parse_string_document(<<'EOPOD');
399=over
400
401=item Pinky
402
403On the list:
404
405=over
406
407=item World Domination
408
409Fight the good fight
410
411=item Go to Europe
412
413(Steve Martin joke)
414
415=back
416
417=item Brain
418
419Not so much
420
421=back
422
423EOPOD
424
425is($results, <<'EOHTML', 'multiparagraph nested lists');
426<dl>
427
428<dt>Pinky</dt>
429<dd>
430
431<p>On the list:</p>
432
433<dl>
434
435<dt>World Domination</dt>
436<dd>
437
438<p>Fight the good fight</p>
439
440</dd>
441<dt>Go to Europe</dt>
442<dd>
443
444<p>(Steve Martin joke)</p>
445
446</dd>
447</dl>
448
449</dd>
450<dt>Brain</dt>
451<dd>
452
453<p>Not so much</p>
454
455</dd>
456</dl>
457
458EOHTML
459
460initialize($parser, $results);
461$parser->parse_string_document(<<'EOPOD');
462=pod
463
464  1 + 1 = 2;
465  2 + 2 = 4;
466
467EOPOD
468
469is($results, <<'EOHTML', "code block");
470<pre><code>  1 + 1 = 2;
471  2 + 2 = 4;</code></pre>
472
473EOHTML
474
475
476initialize($parser, $results);
477$parser->parse_string_document(<<'EOPOD');
478=pod
479
480A plain paragraph with a C<functionname>.
481
482C<< This code is B<important> to E<lt>me>! >>
483
484EOPOD
485is($results, <<"EOHTML", "code entity in a paragraph");
486<p>A plain paragraph with a <code>functionname</code>.</p>
487
488<p><code>This code is <b>important</b> to &lt;me&gt;!</code></p>
489
490EOHTML
491
492
493initialize($parser, $results);
494$parser->html_header("<html>\n<body>");
495$parser->html_footer("</body>\n</html>");
496$parser->parse_string_document(<<'EOPOD');
497=pod
498
499A plain paragraph with body tags turned on.
500EOPOD
501is($results, <<"EOHTML", "adding html body tags");
502<html>
503<body>
504
505<p>A plain paragraph with body tags turned on.</p>
506
507</body>
508</html>
509
510EOHTML
511
512
513initialize($parser, $results);
514$parser->html_css('style.css');
515$parser->html_header(undef);
516$parser->html_footer(undef);
517$parser->parse_string_document(<<'EOPOD');
518=pod
519
520A plain paragraph with body tags and css tags turned on.
521EOPOD
522like($results, qr/<link rel="stylesheet" href="style.css" type="text\/css" \/>/,
523"adding html body tags and css tags");
524
525
526initialize($parser, $results);
527$parser->parse_string_document(<<'EOPOD');
528=pod
529
530A plain paragraph with S<non breaking text>.
531EOPOD
532is($results, <<"EOHTML", "Non breaking text in a paragraph");
533<p>A plain paragraph with <span style="white-space: nowrap;">non breaking text</span>.</p>
534
535EOHTML
536
537initialize($parser, $results);
538$parser->parse_string_document(<<'EOPOD');
539=pod
540
541A plain paragraph with a L<Newlines>.
542EOPOD
543is($results, <<"EOHTML", "Link entity in a paragraph");
544<p>A plain paragraph with a <a href="$PERLDOC?Newlines">Newlines</a>.</p>
545
546EOHTML
547
548initialize($parser, $results);
549$parser->parse_string_document(<<'EOPOD');
550=pod
551
552A plain paragraph with a L<perlport/Newlines>.
553EOPOD
554is($results, <<"EOHTML", "Link entity in a paragraph");
555<p>A plain paragraph with a <a href="$PERLDOC?perlport#Newlines">&quot;Newlines&quot; in perlport</a>.</p>
556
557EOHTML
558
559initialize($parser, $results);
560$parser->parse_string_document(<<'EOPOD');
561=pod
562
563A plain paragraph with a L<Boo|http://link.included.here>.
564EOPOD
565is($results, <<"EOHTML", "A link in a paragraph");
566<p>A plain paragraph with a <a href="http://link.included.here">Boo</a>.</p>
567
568EOHTML
569
570initialize($parser, $results);
571$parser->parse_string_document(<<'EOPOD');
572=pod
573
574A plain paragraph with a L<http://link.included.here>.
575EOPOD
576is($results, <<"EOHTML", "A link in a paragraph");
577<p>A plain paragraph with a <a href="http://link.included.here">http://link.included.here</a>.</p>
578
579EOHTML
580
581initialize($parser, $results);
582$parser->parse_string_document(<<'EOPOD');
583=pod
584
585A plain paragraph with a L<http://link.included.here?o=1&p=2>.
586EOPOD
587is($results, <<"EOHTML", "A link in a paragraph");
588<p>A plain paragraph with a <a href="http://link.included.here?o=1&amp;p=2">http://link.included.here?o=1&amp;p=2</a>.</p>
589
590EOHTML
591
592initialize($parser, $results);
593$parser->parse_string_document(<<'EOPOD');
594=pod
595
596A plain paragraph with B<bold text>.
597EOPOD
598is($results, <<"EOHTML", "Bold text in a paragraph");
599<p>A plain paragraph with <b>bold text</b>.</p>
600
601EOHTML
602
603initialize($parser, $results);
604$parser->parse_string_document(<<'EOPOD');
605=pod
606
607A plain paragraph with I<italic text>.
608EOPOD
609is($results, <<"EOHTML", "Italic text in a paragraph");
610<p>A plain paragraph with <i>italic text</i>.</p>
611
612EOHTML
613
614initialize($parser, $results);
615$parser->parse_string_document(<<'EOPOD');
616=pod
617
618A plain paragraph with a F<filename>.
619EOPOD
620is($results, <<"EOHTML", "File name in a paragraph");
621<p>A plain paragraph with a <i>filename</i>.</p>
622
623EOHTML
624
625# It's not important that 's (apostrophes) be encoded for XHTML output.
626initialize($parser, $results);
627$parser->parse_string_document(<<'EOPOD');
628=pod
629
630  # this header is very important & dont you forget it
631  my $text = "File is: " . <FILE>;
632EOPOD
633is($results, <<"EOHTML", "Verbatim text with encodable entities");
634<pre><code>  # this header is very important &amp; dont you forget it
635  my \$text = &quot;File is: &quot; . &lt;FILE&gt;;</code></pre>
636
637EOHTML
638
639initialize($parser, $results);
640$parser->parse_string_document(<<'EOPOD');
641=pod
642
643A text paragraph using E<sol> and E<verbar> special POD entities.
644
645EOPOD
646is($results, <<"EOHTML", "Text with decodable entities");
647<p>A text paragraph using / and | special POD entities.</p>
648
649EOHTML
650
651initialize($parser, $results);
652$parser->parse_string_document(<<'EOPOD');
653=pod
654
655A text paragraph using numeric POD entities: E<60>, E<62>.
656
657EOPOD
658is($results, <<"EOHTML", "Text with numeric entities");
659<p>A text paragraph using numeric POD entities: &lt;, &gt;.</p>
660
661EOHTML
662
663SKIP: for my $use_html_entities (0, 1) {
664  if ($use_html_entities and not $Pod::Simple::XHTML::HAS_HTML_ENTITIES) {
665    skip("HTML::Entities not installed", 3);
666  }
667  local $Pod::Simple::XHTML::HAS_HTML_ENTITIES = $use_html_entities;
668  initialize($parser, $results);
669  $parser->codes_in_verbatim(1);
670  $parser->parse_string_document(<<'EOPOD');
671=pod
672
673  # this header is very important & dont you forget it
674  B<my $file = <FILEE<gt> || Blank!;>
675  my $text = "File is: " . <FILE>;
676EOPOD
677is($results, <<"EOHTML", "Verbatim text with markup and embedded formatting");
678<pre><code>  # this header is very important &amp; dont you forget it
679  <b>my \$file = &lt;FILE&gt; || Blank!;</b>
680  my \$text = &quot;File is: &quot; . &lt;FILE&gt;;</code></pre>
681
682EOHTML
683
684  # Specify characters to encode.
685  initialize($parser, $results);
686  $parser->html_encode_chars('><"&T');
687  $parser->parse_string_document(<<'EOPOD');
688=pod
689
690This is Anna's "Answer" to the <q>Question</q>.
691
692=cut
693
694EOPOD
695my $T = $use_html_entities ? 84 : 'x54';
696is($results, <<"EOHTML", 'HTML Entities should be only for specified characters');
697<p>&#$T;his is Anna's &quot;Answer&quot; to the &lt;q&gt;Question&lt;/q&gt;.</p>
698
699EOHTML
700
701  # Keep =encoding out of content.
702  initialize($parser, $results);
703  $parser->parse_string_document("=encoding utf-8\n\n=head1 NAME\n");
704  is($results, <<"EOHTML", 'Encoding should not be in content')
705<h1 id="NAME">NAME</h1>
706
707EOHTML
708
709}
710
711
712ok $parser = Pod::Simple::XHTML->new, 'Construct a new parser';
713$results = '';
714$parser->output_string( \$results ); # Send the resulting output to a string
715ok $parser->parse_string_document( "=head1 Poit!" ), 'Parse with headers';
716like $results, qr{\Q<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />},
717    'Should have proper http-equiv meta tag';
718
719ok $parser = Pod::Simple::XHTML->new, 'Construct a new parser again';
720ok $parser->html_charset('UTF-8'), 'Set the html charset to UTF-8';
721$results = '';
722$parser->output_string( \$results ); # Send the resulting output to a string
723ok $parser->parse_string_document( "=head1 Poit!" ), 'Parse with headers';
724like $results, qr{\Q<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />},
725    'Should have http-equiv meta tag with UTF-8';
726
727# Test the link generation methods.
728is $parser->resolve_pod_page_link('Net::Ping', 'INSTALL'),
729    "$PERLDOC?Net::Ping#INSTALL",
730    'POD link with fragment';
731is $parser->resolve_pod_page_link('perlpodspec'),
732    "$PERLDOC?perlpodspec", 'Simple POD link';
733is $parser->resolve_pod_page_link(undef, 'SYNOPSIS'), '#SYNOPSIS',
734    'Simple fragment link';
735is $parser->resolve_pod_page_link(undef, 'this that'), '#this-that',
736    'Fragment link with space';
737is $parser->resolve_pod_page_link('perlpod', 'this that'),
738    "$PERLDOC?perlpod#this-that",
739    'POD link with fragment with space';
740
741is $parser->resolve_man_page_link('crontab(5)', 'EXAMPLE CRON FILE'),
742    "${MANURL}5/crontab", 'Man link with fragment';
743is $parser->resolve_man_page_link('crontab(5)'),
744    "${MANURL}5/crontab", 'Man link without fragment';
745is $parser->resolve_man_page_link('crontab'),
746    "${MANURL}1/crontab", 'Man link without section';
747
748# Make sure that batch_mode_page_object_init() works.
749ok $parser->batch_mode_page_object_init(0, 0, 0, 0, 6),
750    'Call batch_mode_page_object_init()';
751ok $parser->batch_mode, 'We should be in batch mode';
752is $parser->batch_mode_current_level, 6,
753    'The level should have been set';
754
755######################################
756
757sub initialize {
758	$_[0] = Pod::Simple::XHTML->new ();
759        $_[0]->html_header("");
760        $_[0]->html_footer("");
761	$_[0]->output_string( \$results ); # Send the resulting output to a string
762	$_[1] = '';
763	return;
764}
765