File Coverage

blib/lib/Pod/Tree/Node.pm
Criterion Covered Total %
statement 359 385 93.2
branch 113 126 89.6
condition 30 33 90.9
subroutine 87 97 89.6
pod 29 70 41.4
total 618 711 86.9


line stmt bran cond sub pod time code
1             # Copyright (c) 1999-2004 by Steven McDougall. This module is free
2             # software; you can redistribute it and/or modify it under the same
3             # terms as Perl itself.
4              
5             package Pod::Tree::Node;
6              
7 19     19   651261 use 5.006;
  19         77  
8 19     19   137 use strict;
  19         61  
  19         474  
9 19     19   95 use warnings;
  19         40  
  19         741  
10 19     19   10147 use Pod::Escapes ();
  19         66102  
  19         101124  
11              
12             our $VERSION = '1.30';
13              
14             sub root # ctor
15             {
16 84     84 1 190 my ( $class, $children ) = @_;
17              
18 84         258 my $node = {
19             type => 'root',
20             children => $children
21             };
22              
23 84         310 bless $node, $class;
24             }
25              
26             sub code #ctor
27             {
28 44     44 1 93 my ( $class, $paragraph ) = @_;
29              
30 44         117 my $node = {
31             type => 'code',
32             text => $paragraph
33             };
34              
35 44         120 bless $node, $class;
36             }
37              
38             sub verbatim # ctor
39             {
40 79     79 1 159 my ( $class, $paragraph ) = @_;
41              
42 79         228 my $node = {
43             type => 'verbatim',
44             raw => $paragraph,
45             text => $paragraph
46             };
47              
48 79         189 bless $node, $class;
49             }
50              
51             my %Argumentative = map { $_ => 1 } qw(=over
52             =for =begin =end);
53              
54             sub command # ctor
55             {
56 1240     1240 1 1992 my ( $class, $paragraph ) = @_;
57 1240         1651 my ( $command, $arg, $text );
58              
59 1240         3071 ($command) = split( /\s/, $paragraph );
60              
61 1240 100       2486 if ( $Argumentative{$command} ) {
62 247         827 ( $command, $arg, $text ) = split( /\s+/, $paragraph, 3 );
63             }
64             else {
65 993         2557 ( $command, $text ) = split( /\s+/, $paragraph, 2 );
66 993         1541 $arg = '';
67             }
68              
69 1240         3062 $command =~ s/^=//;
70              
71 1240         4413 my $node = {
72             type => 'command',
73             raw => $paragraph,
74             command => $command,
75             arg => $arg,
76             text => $text
77             };
78              
79 1240         2858 bless $node, $class;
80             }
81              
82             sub ordinary # ctor
83             {
84 1026     1026 1 1687 my ( $class, $paragraph ) = @_;
85              
86 1026         2576 my $node = {
87             type => 'ordinary',
88             raw => $paragraph,
89             text => $paragraph
90             };
91              
92 1026         2231 bless $node, $class;
93             }
94              
95             sub letter # ctor
96             {
97 975     975 0 1720 my ( $class, $token ) = @_;
98              
99 975         2901 my $node = {
100             type => 'letter',
101             letter => substr( $token, 0, 1 ),
102             width => $token =~ tr/
103             };
104              
105 975         1948 bless $node, $class;
106             }
107              
108             sub sequence # ctor
109             {
110 975     975 1 1622 my ( $class, $letter, $children ) = @_;
111              
112             my $node = {
113             type => 'sequence',
114 975         2762 'letter' => $letter->{'letter'},
115             children => $children
116             };
117              
118 975         1919 bless $node, $class;
119             }
120              
121             sub text # ctor
122             {
123 3554     3554 1 6188 my ( $class, $text ) = @_;
124              
125 3554         8445 my $node = {
126             type => 'text',
127             text => $text
128             };
129              
130 3554         7085 bless $node, $class;
131             }
132              
133             sub target # ctor
134             {
135 277     277 1 541 my ( $class, $children ) = @_;
136              
137 277         711 my $node = bless {
138             type => 'target',
139             children => $children
140             }, $class;
141              
142 277         638 $node->unescape;
143 277         556 my $text = $node->get_deep_text;
144              
145 277 100       778 if ( $text =~ m(^[A-Za-z]+:(?!:)) ) # a URL
146             {
147 18         55 $node->{page} = $text;
148 18         30 $node->{section} = '';
149 18         33 $node->{domain} = 'HTTP';
150             }
151             else # a POD link
152             {
153 259         472 my ( $page, $section ) = SplitTarget($text);
154 259         545 $node->{page} = $page;
155 259         401 $node->{section} = $section;
156 259         509 $node->{domain} = 'POD';
157             }
158              
159 277         642 $node;
160             }
161              
162             sub SplitTarget {
163 259     259 0 458 my $text = shift;
164 259         376 my ( $page, $section );
165              
166 259 100       602 if ( $text =~ /^"(.*)"$/s ) # L<"sec">;
167             {
168 52         88 $page = '';
169 52         133 $section = $1;
170             }
171             else # all other cases
172             {
173 207         543 ( $page, $section ) = ( split( m(/), $text, 2 ), '', '' );
174              
175 207         417 $page =~ s/\s*\(\d\)$//; # ls (1) -> ls
176 207         519 $section =~ s( ^" | "$ )()xg; # lose the quotes
177              
178             # L
(without quotes)
179 207 100 100     986 if ( $page !~ /^[\w.-]+(::[\w.-]+)*$/ and $section eq '' ) {
180 51         92 $section = $page;
181 51         87 $page = '';
182             }
183             }
184              
185 259         508 $section =~ s( \s*\n\s* )( )xg; # close line breaks
186 259         766 $section =~ s( ^\s+ | \s+$ )()xg; # clip leading and trailing WS
187              
188 259         779 ( $page, $section );
189             }
190              
191             sub link # ctor
192             {
193 0     0 1 0 my ( $class, $node, $page, $section ) = @_;
194              
195 0         0 my $target = bless {
196             type => 'target',
197             domain => 'POD',
198             children => [$node],
199             page => $page,
200             section => $section
201             }, $class;
202              
203 0         0 my $link = bless {
204             type => 'sequence',
205             letter => 'L',
206             children => [$node],
207             target => $target
208             }, $class;
209              
210 0         0 $link;
211             }
212              
213 5871     5871 0 15878 sub is_code { shift->{type} eq 'code' }
214 0     0 0 0 sub is_command { shift->{type} eq 'command' }
215 2242     2242 0 4788 sub is_for { shift->{type} eq 'for' }
216 0     0 0 0 sub is_item { shift->{type} eq 'item' }
217 2317     2317 0 8075 sub is_letter { shift->{type} eq 'letter' }
218 0     0 0 0 sub is_list { shift->{type} eq 'list' }
219 0     0 0 0 sub is_ordinary { shift->{type} eq 'ordinary' }
220 293     293 0 822 sub is_root { shift->{type} eq 'root' }
221 14272     14272 0 36345 sub is_sequence { shift->{type} eq 'sequence' }
222 5136     5136 0 13735 sub is_text { shift->{type} eq 'text' }
223 5740     5740 0 16600 sub is_verbatim { shift->{type} eq 'verbatim' }
224              
225             sub is_link {
226 6841     6841 0 8222 my $node = shift;
227 6841 100       9803 $node->is_sequence and $node->{'letter'} eq 'L';
228             }
229              
230             sub is_pod {
231 144     144 0 215 my $node = shift;
232 144   100     254 not $node->is_code and not $node->is_c_cut and not $node->is_c_pod;
233             }
234              
235             sub is_c_head1 {
236 272     272 0 338 my $node = shift;
237 272 100       934 $node->{type} eq 'command' and $node->{'command'} eq 'head1';
238             }
239              
240             sub is_c_head2 {
241 281     281 0 365 my $node = shift;
242 281 100       1008 $node->{type} eq 'command' and $node->{'command'} eq 'head2';
243             }
244              
245             sub is_c_head3 {
246 0     0 0 0 my $node = shift;
247 0 0       0 $node->{type} eq 'command' and $node->{'command'} eq 'head3';
248             }
249              
250             sub is_c_head4 {
251 0     0 0 0 my $node = shift;
252 0 0       0 $node->{type} eq 'command' and $node->{'command'} eq 'head4';
253             }
254              
255             sub is_c_cut {
256 130     130 0 191 my $node = shift;
257 130 100       660 $node->{type} eq 'command' and $node->{'command'} eq 'cut';
258             }
259              
260             sub is_c_pod {
261 124     124 0 200 my $node = shift;
262 124 100       630 $node->{type} eq 'command' and $node->{'command'} eq 'pod';
263             }
264              
265             sub is_c_over {
266 2311     2311 0 2788 my $node = shift;
267 2311 100       6986 $node->{type} eq 'command' and $node->{'command'} eq 'over';
268             }
269              
270             sub is_c_back {
271 2487     2487 0 3038 my $node = shift;
272 2487 100       6688 $node->{type} eq 'command' and $node->{'command'} eq 'back';
273             }
274              
275             sub is_c_item {
276 2762     2762 0 3402 my $node = shift;
277 2762 100       8514 $node->{type} eq 'command' and $node->{'command'} eq 'item';
278             }
279              
280             sub is_c_for {
281 2357     2357 0 2981 my $node = shift;
282 2357 100       7324 $node->{type} eq 'command' and $node->{'command'} eq 'for';
283             }
284              
285             sub is_c_begin {
286 2357     2357 0 2947 my $node = shift;
287 2357 100       7015 $node->{type} eq 'command' and $node->{'command'} eq 'begin';
288             }
289              
290             sub is_c_end {
291 32     32 0 43 my $node = shift;
292 32 100       173 $node->{type} eq 'command' and $node->{'command'} eq 'end';
293             }
294              
295 92     92 1 211 sub get_arg { shift->{arg} }
296 19     19 0 38 sub get_back { shift->{back} }
297 3532     3532 1 6369 sub get_children { shift->{children} }
298 295     295 1 753 sub get_command { shift->{'command'} }
299 222     222 1 490 sub get_domain { shift->{domain} }
300 420     420 1 948 sub get_item_type { shift->{item_type} }
301 1081     1081 1 2507 sub get_letter { shift->{'letter'} }
302 190     190 1 435 sub get_list_type { shift->{list_type} }
303 222     222 1 676 sub get_page { shift->{page} }
304 60     60 1 142 sub get_raw { shift->{raw} }
305 27     27 1 46 sub get_raw_kids { shift->{raw_kids} }
306 206     206 1 538 sub get_section { shift->{section} }
307 1560     1560 1 2289 sub get_siblings { shift->{siblings} }
308 250     250 1 535 sub get_target { shift->{'target'} }
309 2759     2759 1 5967 sub get_text { shift->{'text'} }
310 3825     3825 1 7043 sub get_type { shift->{'type'} }
311 0     0 0 0 sub get_url { shift->{'url'} }
312              
313             sub get_brackets {
314 3     3 1 5 my $node = shift;
315 3         7 my $brackets = $node->{brackets};
316 3         4 $brackets;
317             }
318              
319             sub get_deep_text {
320 1735     1735 1 2321 my $node = shift;
321              
322 1735         2715 for ( $node->get_type ) {
323 1735 100       6373 /text/ and return $node->{'text'};
324 843 50       1688 /verbatim/ and return $node->{'text'};
325             }
326              
327 843         1246 join '', map { $_->get_deep_text } @{ $node->{children} };
  999         1747  
  843         1713  
328             }
329              
330             sub force_text {
331 234     234 0 391 my ( $node, $text ) = @_;
332 234         333 $node->{type} = 'text';
333 234         358 $node->{'text'} = $text;
334 234         368 undef $node->{children};
335             }
336              
337             sub force_for {
338 22     22 0 40 my $node = shift;
339 22         42 $node->{type} = 'for';
340              
341 22         83 my ($bracket) = $node->{raw} =~ /^(=\w+\s+\w+\s+)/;
342              
343 22         73 $node->{brackets} = [$bracket];
344             }
345              
346             sub parse_begin {
347 8     8 0 23 my ( $node, $nodes ) = @_;
348              
349 8         17 my $foreign;
350             my @raw;
351 8         28 while (@$nodes) {
352 32         82 $foreign = shift @$nodes;
353 32 100       71 $foreign->is_c_end and last;
354 24         79 push @raw, $foreign->{'raw'};
355             }
356 8         45 $node->{'text'} = join '', @raw;
357              
358 8         21 my $interpreter = $foreign->{arg};
359             $interpreter
360             and $interpreter ne $node->{arg}
361 8 50 33     50 and $node->_warn("Mismatched =begin/=end tags around\n$node->{'text'}");
362              
363 8         19 $node->{type} = 'for';
364 8         40 $node->{brackets} = [ $node->{raw}, $foreign->{raw} ];
365             }
366              
367             sub set_children {
368 84     84 0 207 my ( $node, $children ) = @_;
369 84         250 $node->{children} = $children;
370             }
371              
372             sub make_sequences {
373 2212     2212 0 2792 my $node = shift;
374 2212         3207 my $text = $node->{'text'};
375 2212         14976 my @tokens = split /( [A-Z]<<+\s+ | [A-Z]< | \s+>>+ | > )/x, $text;
376 2212         3858 my $sequences = _parse_text( \@tokens );
377 2212         5521 $node->{children} = $sequences;
378             }
379              
380             sub _parse_text {
381 2212     2212   2835 my $tokens = shift;
382 2212         3107 my ( @stack, @width );
383              
384 2212         3906 while (@$tokens) {
385 5732         8116 my $token = shift @$tokens;
386 5732 100       10150 length $token or next;
387              
388 5302 100       10494 $token =~ /^[A-Z]
389 975         1589 my $width = $token =~ tr/
390 975         1456 push @width, $width;
391 975         1863 my $node = Pod::Tree::Node->letter($token);
392 975         1544 push @stack, $node;
393 975         2428 next;
394             };
395              
396 4327 100 100     14738 @width and $token =~ />{$width[-1],}$/ and do {
397 975         1718 my $width = pop @width;
398 975         1966 my ( $letter, $interior ) = _pop_sequence( \@stack, $width );
399 975         2454 my $node = Pod::Tree::Node->sequence( $letter, $interior );
400 975         1506 push @stack, $node;
401 975         5169 $token =~ s/^\s*>{$width}//;
402 975         2252 my @tokens = split //, $token;
403 975         1513 unshift @$tokens, @tokens;
404 975         3122 next;
405             };
406              
407 3352         6319 my $node = Pod::Tree::Node->text($token);
408 3352         7924 push @stack, $node;
409             }
410              
411 2212 50       3785 if (@width) {
412 0         0 my @text = map { $_->get_deep_text } @stack;
  0         0  
413 0         0 Pod::Tree::Node->_warn("Missing '>' delimiter in\n@text");
414             }
415              
416 2212         3862 \@stack;
417             }
418              
419             sub _pop_sequence {
420 975     975   1777 my ( $stack, $width ) = @_;
421 975         1284 my ( $node, @interior );
422              
423 975         1750 while (@$stack) {
424 2317         3025 $node = pop @$stack;
425             $node->is_letter
426 2317 100 66     3644 and $node->{width} == $width
427             and return ( $node, \@interior );
428 1342         2924 unshift @interior, $node;
429             }
430              
431 0         0 my @text = map { $_->get_deep_text } @interior;
  0         0  
432 0         0 $node->_warn("Mismatched sequence delimiters around\n@text");
433              
434 0         0 $node = Pod::Tree::Node->letter(' ');
435 0         0 $node, \@interior;
436             }
437              
438             sub parse_links {
439 6747     6747 0 8241 my $node = shift;
440              
441 6747 100       9328 $node->is_link and $node->_parse_link;
442              
443 6747         9869 my $children = $node->{children};
444 6747         11638 for my $child (@$children) {
445 6663         9581 $child->parse_links;
446             }
447             }
448              
449             sub _parse_link {
450 277     277   398 my $node = shift;
451              
452 277         504 $node->{raw_kids} = $node->clone->{children};
453              
454 277         605 my $children = $node->{children};
455 277         482 my ( $text_kids, $target_kids ) = SplitBar($children);
456              
457 277         470 $node->{children} = $text_kids;
458 277         540 $node->{'target'} = Pod::Tree::Node->target($target_kids);
459             }
460              
461             sub SplitBar {
462 277     277 0 382 my $children = shift;
463 277         396 my ( @text, @link );
464              
465 277         603 while (@$children) {
466 333         449 my $child = shift @$children;
467              
468 333 100       602 $child->is_text or do {
469 51         80 push @text, $child;
470 51         119 next;
471             };
472              
473 282         810 my ( $text, $link ) = split m(\|), $child->{'text'}, 2;
474 282 100       602 $link and do {
475 101 50       272 push @text, Pod::Tree::Node->text($text) if $text;
476 101         209 push @link, Pod::Tree::Node->text($link), @$children;
477 101         448 return ( \@text, \@link );
478             };
479              
480 181         440 push @text, $child;
481             }
482              
483 176         401 ( \@text, \@text );
484             }
485              
486             sub unescape {
487 7431     7431 0 9010 my $node = shift;
488              
489 7431         9452 my $children = $node->{children};
490 7431         10388 for my $child (@$children) {
491 7070         10603 $child->unescape;
492             }
493              
494 7431 100       10382 $node->is_sequence and $node->_unescape_sequence;
495             }
496              
497             sub _unescape_sequence {
498 1022     1022   1367 my $node = shift;
499              
500 1022         1508 for ( $node->{'letter'} ) {
501 1022 100       2006 /Z/ and $node->force_text(''), last;
502 1007 100       2229 /E/ and do {
503 219         358 my $child = $node->{children}[0];
504 219 50       372 $child or last;
505 219         401 my $text = $child->_unescape_text;
506 219 50       2542 $text and $node->force_text($text);
507 219         538 last;
508             };
509             }
510             }
511              
512             sub _unescape_text {
513 219     219   290 my $node = shift;
514 219         294 my $text = $node->{'text'};
515              
516 219 50       499 defined $text ? Pod::Escapes::e2char($text) : "E";
517             }
518              
519             sub consolidate {
520 5988     5988 0 7110 my $node = shift;
521 5988         7519 my $old = $node->{children};
522 5988 100 100     14733 $old and @$old or return;
523              
524 2589         3546 my $new = [];
525              
526 2589         3950 push @$new, shift @$old;
527              
528 2589         4397 while (@$old) {
529 3862 100 100     5788 if ( $new->[-1]->is_text and $old->[0]->is_text
      100        
      100        
      100        
      100        
530             or $new->[-1]->is_verbatim and $old->[0]->is_verbatim
531             or $new->[-1]->is_code and $old->[0]->is_code )
532             {
533 547         929 $new->[-1]{'text'} .= $old->[0]{'text'};
534 547         1338 shift @$old;
535             }
536             else {
537 3315         7678 push @$new, shift @$old;
538             }
539             }
540              
541 2589         3362 $node->{children} = $new;
542              
543 2589         3629 for my $child (@$new) {
544 5904         8543 $child->consolidate;
545             }
546             }
547              
548             sub make_lists {
549 84     84 0 142 my $root = shift;
550 84         136 my $nodes = $root->{children};
551              
552 84         212 $root->_make_lists($nodes);
553             }
554              
555             sub _make_lists {
556 293     293   545 my ( $node, $old ) = @_;
557 293         428 my $new = [];
558 293         417 my $back;
559              
560 293         543 while (@$old) {
561 1794         2363 my $child = shift @$old;
562 1794 100       2788 $child->is_c_over and $child->_make_lists($old);
563 1794 100       3004 $child->is_c_item and $child->_make_item($old);
564 1794 100       2996 $child->is_c_back and $back = $child, last;
565 1596         3428 push @$new, $child;
566             }
567              
568 293         496 $node->{children} = $new;
569              
570 293 100       528 $node->is_root and return;
571              
572 209         323 $node->{type} = 'list';
573 209         292 $node->{back} = $back;
574 209         407 $node->_set_list_type;
575             }
576              
577             sub _set_list_type {
578 209     209   277 my $list = shift;
579 209         285 my $children = $list->{children};
580              
581 209         438 $list->{list_type} = ''; # -w
582              
583 209         362 for my $child (@$children) {
584 198 100       391 $child->{type} eq 'item' or next;
585 187         292 $list->{list_type} = $child->{item_type};
586 187         332 last;
587             }
588             }
589              
590             sub _make_item {
591 462     462   713 my ( $item, $old ) = @_;
592 462         785 my $siblings = [];
593              
594 462         820 while (@$old) {
595 968         1269 my $sibling = $old->[0];
596 968 100       1355 $sibling->is_c_item and last;
597 693 100       1175 $sibling->is_c_back and last;
598              
599 517         740 shift @$old;
600 517 100       778 $sibling->is_c_over and do {
601 55         136 $sibling->_make_lists($old);
602             };
603 517         1142 push @$siblings, $sibling;
604             }
605              
606 462         771 $item->{type} = 'item';
607 462         669 $item->{siblings} = $siblings;
608 462         732 $item->_set_item_type;
609             }
610              
611             sub _set_item_type {
612 462     462   559 my $item = shift;
613 462         658 my $text = $item->{'text'};
614              
615 462 100       1576 $text =~ m(^\s* \* \s*$ )x and $item->{item_type} = 'bullet';
616 462 100       1352 $text =~ m(^\s* \d+ \s*$ )x and $item->{item_type} = 'number';
617 462 100       1212 $item->{item_type} or $item->{item_type} = 'text';
618             }
619              
620             sub clone {
621 696     696 1 903 my $node = shift;
622 696         2340 my $clone = {%$node};
623              
624 696         1182 my $children = $node->{children};
625 696         1247 $clone->{children} = [ map { $_->clone } @$children ];
  419         701  
626              
627 696         1964 bless $clone, ref $node;
628             }
629              
630             my $Indent;
631             my $String;
632              
633             sub dump {
634 15     15 1 34 my $node = shift;
635              
636 15         26 $Indent = 0;
637 15         99 $String = '';
638 15         45 $node->_dump;
639 15         135 $String;
640             }
641              
642             sub _dump {
643 1266     1266   1567 my $node = shift;
644 1266         1744 my $type = $node->get_type;
645              
646 1266         2526 $String .= ' ' x $Indent . uc $type . " ";
647              
648 1266         1771 for ($type) {
649 1266 100       2222 /command/ and $String .= $node->_dump_command;
650 1266 100       2103 /code/ and $String .= $node->_dump_code;
651 1266 100       2061 /for/ and $String .= $node->_dump_for;
652 1266 100       2167 /item/ and $String .= $node->_dump_item;
653 1266 100       2183 /list/ and $String .= $node->_dump_list;
654 1266 100       2045 /ordinary/ and $String .= "\n";
655 1266 100       1997 /root/ and $String .= "\n";
656 1266 100       2018 /sequence/ and $String .= $node->_dump_sequence;
657 1266 100       2521 /text/ and $String .= $node->_dump_text;
658 1266 100       2487 /verbatim/ and $String .= $node->_dump_verbatim;
659             }
660              
661 1266         2511 $node->_dump_children;
662 1266         1865 $node->_dump_siblings;
663             }
664              
665             sub _dump_command {
666 65     65   108 my $node = shift;
667 65         123 my $command = $node->get_command;
668 65         122 my $arg = $node->get_arg;
669              
670 65         154 "$command $arg\n";
671             }
672              
673             sub _dump_code {
674 11     11   21 my $node = shift;
675              
676 11         18 my $text = _indent( $node->get_text, 3 );
677 11         24 my $block = "\n{\n$text}\n";
678              
679 11         19 _indent( $block, $Indent );
680             }
681              
682             sub _dump_for {
683 3     3   5 my $node = shift;
684 3         7 my $arg = $node->get_arg;
685 3         7 my $text = _indent( $node->get_text, $Indent + 3 );
686              
687 3         10 "$arg\n$text\n";
688             }
689              
690             sub _dump_item {
691 168     168   228 my $node = shift;
692 168         262 uc $node->get_item_type . "\n";
693             }
694              
695             sub _dump_list {
696 76     76   118 my $node = shift;
697 76         124 uc $node->get_list_type . "\n";
698             }
699              
700             sub _dump_sequence {
701 94     94   129 my $node = shift;
702 94         152 my $letter = $node->get_letter;
703 94 100       149 my $link = $node->is_link ? $node->_dump_target : '';
704              
705 94         198 "$letter$link\n";
706             }
707              
708             sub _dump_text {
709 588     588   767 my $node = shift;
710 588         853 my $text = $node->get_text;
711              
712 588         1055 $text =~ s/([\x80-\xff])/sprintf("\\x%02x", ord($1))/eg;
  12         41  
713              
714 588         897 my $indent = ' ' x ( $Indent + 5 );
715 588         1545 $text =~ s( (?<=\n) (?=.) )($indent)xg;
716 588         1118 "$text\n";
717             }
718              
719             sub _dump_verbatim {
720 6     6   16 my $node = shift;
721 6         15 "\n" . $node->get_text . "\n";
722             }
723              
724             sub _dump_target {
725 28     28   37 my $node = shift;
726 28         45 my $target = $node->get_target;
727 28         48 my $page = $target->{page};
728 28         39 my $section = $target->{section};
729 28         62 " $page / $section";
730             }
731              
732             sub _dump_children {
733 1266     1266   1672 my $node = shift;
734 1266         1740 my $children = $node->get_children;
735 1266 100       2569 $children and DumpList( $children, '{', '}' );
736             }
737              
738             sub _dump_siblings {
739 1266     1266   1526 my $node = shift;
740 1266         2130 my $siblings = $node->get_siblings;
741 1266 100       2480 $siblings and DumpList( $siblings, '[', ']' );
742             }
743              
744             sub DumpList {
745 826     826 0 1372 my ( $nodes, $open, $close ) = @_;
746              
747 826         1524 $String .= ' ' x $Indent . "$open\n";
748 826         1009 $Indent += 3;
749              
750 826         1218 for my $node (@$nodes) {
751 1251         1933 $node->_dump;
752             }
753              
754 826         1033 $Indent -= 3;
755 826         1660 $String .= ' ' x $Indent . "$close\n";
756             }
757              
758             sub _indent {
759 25     25   50 my ( $text, $spaces ) = @_;
760 25         37 my $indent = ' ' x $spaces;
761 25         165 $text =~ s( (?<=\n) (?=.) )($indent)xg;
762 25         64 $indent . $text;
763             }
764              
765             sub _warn {
766 0     0   0 my ( $node, $message ) = @_;
767              
768 0         0 my $filename = $node->get_filename;
769 0 0       0 my $tag = $filename ? "in $filename" : $filename;
770 0         0 warn "$message $tag\n";
771             }
772              
773             sub set_filename {
774 150     150 1 323 my ( $package, $filename ) = @_;
775              
776 150         318 $Pod::Tree::Node::filename = $filename;
777             }
778              
779             sub get_filename {
780 0     0 0   $Pod::Tree::Node::filename;
781             }
782              
783             1
784              
785             __END__