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   626434 use 5.006;
  19         72  
8 19     19   111 use strict;
  19         79  
  19         477  
9 19     19   105 use warnings;
  19         41  
  19         683  
10 19     19   9725 use Pod::Escapes ();
  19         64806  
  19         100314  
11              
12             our $VERSION = '1.31';
13              
14             sub root # ctor
15             {
16 84     84 1 230 my ( $class, $children ) = @_;
17              
18 84         295 my $node = {
19             type => 'root',
20             children => $children
21             };
22              
23 84         297 bless $node, $class;
24             }
25              
26             sub code #ctor
27             {
28 44     44 1 96 my ( $class, $paragraph ) = @_;
29              
30 44         125 my $node = {
31             type => 'code',
32             text => $paragraph
33             };
34              
35 44         116 bless $node, $class;
36             }
37              
38             sub verbatim # ctor
39             {
40 79     79 1 165 my ( $class, $paragraph ) = @_;
41              
42 79         239 my $node = {
43             type => 'verbatim',
44             raw => $paragraph,
45             text => $paragraph
46             };
47              
48 79         191 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 2030 my ( $class, $paragraph ) = @_;
57 1240         1576 my ( $command, $arg, $text );
58              
59 1240         2987 ($command) = split( /\s/, $paragraph );
60              
61 1240 100       2436 if ( $Argumentative{$command} ) {
62 247         812 ( $command, $arg, $text ) = split( /\s+/, $paragraph, 3 );
63             }
64             else {
65 993         2568 ( $command, $text ) = split( /\s+/, $paragraph, 2 );
66 993         1575 $arg = '';
67             }
68              
69 1240         3049 $command =~ s/^=//;
70              
71 1240         4333 my $node = {
72             type => 'command',
73             raw => $paragraph,
74             command => $command,
75             arg => $arg,
76             text => $text
77             };
78              
79 1240         2811 bless $node, $class;
80             }
81              
82             sub ordinary # ctor
83             {
84 1026     1026 1 1703 my ( $class, $paragraph ) = @_;
85              
86 1026         2498 my $node = {
87             type => 'ordinary',
88             raw => $paragraph,
89             text => $paragraph
90             };
91              
92 1026         2259 bless $node, $class;
93             }
94              
95             sub letter # ctor
96             {
97 975     975 0 1648 my ( $class, $token ) = @_;
98              
99 975         3018 my $node = {
100             type => 'letter',
101             letter => substr( $token, 0, 1 ),
102             width => $token =~ tr/
103             };
104              
105 975         1963 bless $node, $class;
106             }
107              
108             sub sequence # ctor
109             {
110 975     975 1 1563 my ( $class, $letter, $children ) = @_;
111              
112             my $node = {
113             type => 'sequence',
114 975         2699 'letter' => $letter->{'letter'},
115             children => $children
116             };
117              
118 975         1941 bless $node, $class;
119             }
120              
121             sub text # ctor
122             {
123 3554     3554 1 6248 my ( $class, $text ) = @_;
124              
125 3554         8253 my $node = {
126             type => 'text',
127             text => $text
128             };
129              
130 3554         7016 bless $node, $class;
131             }
132              
133             sub target # ctor
134             {
135 277     277 1 486 my ( $class, $children ) = @_;
136              
137 277         680 my $node = bless {
138             type => 'target',
139             children => $children
140             }, $class;
141              
142 277         628 $node->unescape;
143 277         559 my $text = $node->get_deep_text;
144              
145 277 100       787 if ( $text =~ m(^[A-Za-z]+:(?!:)) ) # a URL
146             {
147 18         39 $node->{page} = $text;
148 18         34 $node->{section} = '';
149 18         29 $node->{domain} = 'HTTP';
150             }
151             else # a POD link
152             {
153 259         492 my ( $page, $section ) = SplitTarget($text);
154 259         536 $node->{page} = $page;
155 259         425 $node->{section} = $section;
156 259         445 $node->{domain} = 'POD';
157             }
158              
159 277         632 $node;
160             }
161              
162             sub SplitTarget {
163 259     259 0 378 my $text = shift;
164 259         373 my ( $page, $section );
165              
166 259 100       628 if ( $text =~ /^"(.*)"$/s ) # L<"sec">;
167             {
168 52         80 $page = '';
169 52         140 $section = $1;
170             }
171             else # all other cases
172             {
173 207         554 ( $page, $section ) = ( split( m(/), $text, 2 ), '', '' );
174              
175 207         376 $page =~ s/\s*\(\d\)$//; # ls (1) -> ls
176 207         536 $section =~ s( ^" | "$ )()xg; # lose the quotes
177              
178             # L
(without quotes)
179 207 100 100     973 if ( $page !~ /^[\w.-]+(::[\w.-]+)*$/ and $section eq '' ) {
180 51         91 $section = $page;
181 51         85 $page = '';
182             }
183             }
184              
185 259         461 $section =~ s( \s*\n\s* )( )xg; # close line breaks
186 259         747 $section =~ s( ^\s+ | \s+$ )()xg; # clip leading and trailing WS
187              
188 259         751 ( $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 15642 sub is_code { shift->{type} eq 'code' }
214 0     0 0 0 sub is_command { shift->{type} eq 'command' }
215 2242     2242 0 4802 sub is_for { shift->{type} eq 'for' }
216 0     0 0 0 sub is_item { shift->{type} eq 'item' }
217 2317     2317 0 7911 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 774 sub is_root { shift->{type} eq 'root' }
221 14272     14272 0 36043 sub is_sequence { shift->{type} eq 'sequence' }
222 5136     5136 0 13571 sub is_text { shift->{type} eq 'text' }
223 5740     5740 0 16188 sub is_verbatim { shift->{type} eq 'verbatim' }
224              
225             sub is_link {
226 6841     6841 0 8036 my $node = shift;
227 6841 100       9081 $node->is_sequence and $node->{'letter'} eq 'L';
228             }
229              
230             sub is_pod {
231 144     144 0 206 my $node = shift;
232 144   100     244 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 320 my $node = shift;
237 272 100       967 $node->{type} eq 'command' and $node->{'command'} eq 'head1';
238             }
239              
240             sub is_c_head2 {
241 281     281 0 350 my $node = shift;
242 281 100       1372 $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 196 my $node = shift;
257 130 100       696 $node->{type} eq 'command' and $node->{'command'} eq 'cut';
258             }
259              
260             sub is_c_pod {
261 124     124 0 191 my $node = shift;
262 124 100       665 $node->{type} eq 'command' and $node->{'command'} eq 'pod';
263             }
264              
265             sub is_c_over {
266 2311     2311 0 2825 my $node = shift;
267 2311 100       6859 $node->{type} eq 'command' and $node->{'command'} eq 'over';
268             }
269              
270             sub is_c_back {
271 2487     2487 0 3023 my $node = shift;
272 2487 100       6509 $node->{type} eq 'command' and $node->{'command'} eq 'back';
273             }
274              
275             sub is_c_item {
276 2762     2762 0 3321 my $node = shift;
277 2762 100       8343 $node->{type} eq 'command' and $node->{'command'} eq 'item';
278             }
279              
280             sub is_c_for {
281 2357     2357 0 2883 my $node = shift;
282 2357 100       7514 $node->{type} eq 'command' and $node->{'command'} eq 'for';
283             }
284              
285             sub is_c_begin {
286 2357     2357 0 2886 my $node = shift;
287 2357 100       6872 $node->{type} eq 'command' and $node->{'command'} eq 'begin';
288             }
289              
290             sub is_c_end {
291 32     32 0 45 my $node = shift;
292 32 100       127 $node->{type} eq 'command' and $node->{'command'} eq 'end';
293             }
294              
295 92     92 1 192 sub get_arg { shift->{arg} }
296 19     19 0 34 sub get_back { shift->{back} }
297 3532     3532 1 6385 sub get_children { shift->{children} }
298 295     295 1 772 sub get_command { shift->{'command'} }
299 222     222 1 461 sub get_domain { shift->{domain} }
300 420     420 1 920 sub get_item_type { shift->{item_type} }
301 1081     1081 1 2447 sub get_letter { shift->{'letter'} }
302 190     190 1 449 sub get_list_type { shift->{list_type} }
303 222     222 1 695 sub get_page { shift->{page} }
304 60     60 1 115 sub get_raw { shift->{raw} }
305 27     27 1 51 sub get_raw_kids { shift->{raw_kids} }
306 206     206 1 548 sub get_section { shift->{section} }
307 1560     1560 1 2344 sub get_siblings { shift->{siblings} }
308 250     250 1 494 sub get_target { shift->{'target'} }
309 2759     2759 1 5870 sub get_text { shift->{'text'} }
310 3825     3825 1 7363 sub get_type { shift->{'type'} }
311 0     0 0 0 sub get_url { shift->{'url'} }
312              
313             sub get_brackets {
314 3     3 1 4 my $node = shift;
315 3         5 my $brackets = $node->{brackets};
316 3         6 $brackets;
317             }
318              
319             sub get_deep_text {
320 1735     1735 1 2294 my $node = shift;
321              
322 1735         2642 for ( $node->get_type ) {
323 1735 100       6293 /text/ and return $node->{'text'};
324 843 50       1639 /verbatim/ and return $node->{'text'};
325             }
326              
327 843         1224 join '', map { $_->get_deep_text } @{ $node->{children} };
  999         1781  
  843         1918  
328             }
329              
330             sub force_text {
331 234     234 0 381 my ( $node, $text ) = @_;
332 234         352 $node->{type} = 'text';
333 234         364 $node->{'text'} = $text;
334 234         356 undef $node->{children};
335             }
336              
337             sub force_for {
338 22     22 0 38 my $node = shift;
339 22         43 $node->{type} = 'for';
340              
341 22         87 my ($bracket) = $node->{raw} =~ /^(=\w+\s+\w+\s+)/;
342              
343 22         68 $node->{brackets} = [$bracket];
344             }
345              
346             sub parse_begin {
347 8     8 0 27 my ( $node, $nodes ) = @_;
348              
349 8         16 my $foreign;
350             my @raw;
351 8         29 while (@$nodes) {
352 32         81 $foreign = shift @$nodes;
353 32 100       70 $foreign->is_c_end and last;
354 24         63 push @raw, $foreign->{'raw'};
355             }
356 8         37 $node->{'text'} = join '', @raw;
357              
358 8         23 my $interpreter = $foreign->{arg};
359             $interpreter
360             and $interpreter ne $node->{arg}
361 8 50 33     52 and $node->_warn("Mismatched =begin/=end tags around\n$node->{'text'}");
362              
363 8         22 $node->{type} = 'for';
364 8         38 $node->{brackets} = [ $node->{raw}, $foreign->{raw} ];
365             }
366              
367             sub set_children {
368 84     84 0 196 my ( $node, $children ) = @_;
369 84         239 $node->{children} = $children;
370             }
371              
372             sub make_sequences {
373 2212     2212 0 2862 my $node = shift;
374 2212         3043 my $text = $node->{'text'};
375 2212         14611 my @tokens = split /( [A-Z]<<+\s+ | [A-Z]< | \s+>>+ | > )/x, $text;
376 2212         3953 my $sequences = _parse_text( \@tokens );
377 2212         5319 $node->{children} = $sequences;
378             }
379              
380             sub _parse_text {
381 2212     2212   2754 my $tokens = shift;
382 2212         2875 my ( @stack, @width );
383              
384 2212         3974 while (@$tokens) {
385 5732         8103 my $token = shift @$tokens;
386 5732 100       9941 length $token or next;
387              
388 5302 100       10184 $token =~ /^[A-Z]
389 975         1649 my $width = $token =~ tr/
390 975         1385 push @width, $width;
391 975         1795 my $node = Pod::Tree::Node->letter($token);
392 975         1439 push @stack, $node;
393 975         2089 next;
394             };
395              
396 4327 100 100     14676 @width and $token =~ />{$width[-1],}$/ and do {
397 975         1726 my $width = pop @width;
398 975         1965 my ( $letter, $interior ) = _pop_sequence( \@stack, $width );
399 975         2102 my $node = Pod::Tree::Node->sequence( $letter, $interior );
400 975         1419 push @stack, $node;
401 975         5025 $token =~ s/^\s*>{$width}//;
402 975         2136 my @tokens = split //, $token;
403 975         1504 unshift @$tokens, @tokens;
404 975         3121 next;
405             };
406              
407 3352         6551 my $node = Pod::Tree::Node->text($token);
408 3352         7673 push @stack, $node;
409             }
410              
411 2212 50       3858 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         3924 \@stack;
417             }
418              
419             sub _pop_sequence {
420 975     975   1720 my ( $stack, $width ) = @_;
421 975         1286 my ( $node, @interior );
422              
423 975         1710 while (@$stack) {
424 2317         2921 $node = pop @$stack;
425             $node->is_letter
426 2317 100 66     3688 and $node->{width} == $width
427             and return ( $node, \@interior );
428 1342         2973 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 8069 my $node = shift;
440              
441 6747 100       9115 $node->is_link and $node->_parse_link;
442              
443 6747         10182 my $children = $node->{children};
444 6747         11629 for my $child (@$children) {
445 6663         9624 $child->parse_links;
446             }
447             }
448              
449             sub _parse_link {
450 277     277   367 my $node = shift;
451              
452 277         519 $node->{raw_kids} = $node->clone->{children};
453              
454 277         605 my $children = $node->{children};
455 277         470 my ( $text_kids, $target_kids ) = SplitBar($children);
456              
457 277         447 $node->{children} = $text_kids;
458 277         542 $node->{'target'} = Pod::Tree::Node->target($target_kids);
459             }
460              
461             sub SplitBar {
462 277     277 0 375 my $children = shift;
463 277         401 my ( @text, @link );
464              
465 277         565 while (@$children) {
466 333         448 my $child = shift @$children;
467              
468 333 100       596 $child->is_text or do {
469 51         85 push @text, $child;
470 51         114 next;
471             };
472              
473 282         818 my ( $text, $link ) = split m(\|), $child->{'text'}, 2;
474 282 100       545 $link and do {
475 101 50       272 push @text, Pod::Tree::Node->text($text) if $text;
476 101         206 push @link, Pod::Tree::Node->text($link), @$children;
477 101         425 return ( \@text, \@link );
478             };
479              
480 181         427 push @text, $child;
481             }
482              
483 176         417 ( \@text, \@text );
484             }
485              
486             sub unescape {
487 7431     7431 0 8867 my $node = shift;
488              
489 7431         9185 my $children = $node->{children};
490 7431         10440 for my $child (@$children) {
491 7070         10054 $child->unescape;
492             }
493              
494 7431 100       10318 $node->is_sequence and $node->_unescape_sequence;
495             }
496              
497             sub _unescape_sequence {
498 1022     1022   1317 my $node = shift;
499              
500 1022         1564 for ( $node->{'letter'} ) {
501 1022 100       2018 /Z/ and $node->force_text(''), last;
502 1007 100       2222 /E/ and do {
503 219         347 my $child = $node->{children}[0];
504 219 50       381 $child or last;
505 219         345 my $text = $child->_unescape_text;
506 219 50       2590 $text and $node->force_text($text);
507 219         526 last;
508             };
509             }
510             }
511              
512             sub _unescape_text {
513 219     219   265 my $node = shift;
514 219         309 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 7119 my $node = shift;
521 5988         7729 my $old = $node->{children};
522 5988 100 100     14703 $old and @$old or return;
523              
524 2589         3522 my $new = [];
525              
526 2589         4071 push @$new, shift @$old;
527              
528 2589         4476 while (@$old) {
529 3862 100 100     5949 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         879 $new->[-1]{'text'} .= $old->[0]{'text'};
534 547         1297 shift @$old;
535             }
536             else {
537 3315         7680 push @$new, shift @$old;
538             }
539             }
540              
541 2589         3285 $node->{children} = $new;
542              
543 2589         3666 for my $child (@$new) {
544 5904         8441 $child->consolidate;
545             }
546             }
547              
548             sub make_lists {
549 84     84 0 142 my $root = shift;
550 84         145 my $nodes = $root->{children};
551              
552 84         241 $root->_make_lists($nodes);
553             }
554              
555             sub _make_lists {
556 293     293   523 my ( $node, $old ) = @_;
557 293         455 my $new = [];
558 293         434 my $back;
559              
560 293         561 while (@$old) {
561 1794         2379 my $child = shift @$old;
562 1794 100       2869 $child->is_c_over and $child->_make_lists($old);
563 1794 100       3091 $child->is_c_item and $child->_make_item($old);
564 1794 100       3058 $child->is_c_back and $back = $child, last;
565 1596         3417 push @$new, $child;
566             }
567              
568 293         498 $node->{children} = $new;
569              
570 293 100       540 $node->is_root and return;
571              
572 209         342 $node->{type} = 'list';
573 209         303 $node->{back} = $back;
574 209         360 $node->_set_list_type;
575             }
576              
577             sub _set_list_type {
578 209     209   263 my $list = shift;
579 209         290 my $children = $list->{children};
580              
581 209         453 $list->{list_type} = ''; # -w
582              
583 209         365 for my $child (@$children) {
584 198 100       394 $child->{type} eq 'item' or next;
585 187         262 $list->{list_type} = $child->{item_type};
586 187         312 last;
587             }
588             }
589              
590             sub _make_item {
591 462     462   694 my ( $item, $old ) = @_;
592 462         757 my $siblings = [];
593              
594 462         812 while (@$old) {
595 968         1217 my $sibling = $old->[0];
596 968 100       1385 $sibling->is_c_item and last;
597 693 100       1186 $sibling->is_c_back and last;
598              
599 517         1051 shift @$old;
600 517 100       781 $sibling->is_c_over and do {
601 55         148 $sibling->_make_lists($old);
602             };
603 517         1164 push @$siblings, $sibling;
604             }
605              
606 462         753 $item->{type} = 'item';
607 462         714 $item->{siblings} = $siblings;
608 462         773 $item->_set_item_type;
609             }
610              
611             sub _set_item_type {
612 462     462   569 my $item = shift;
613 462         685 my $text = $item->{'text'};
614              
615 462 100       1651 $text =~ m(^\s* \* \s*$ )x and $item->{item_type} = 'bullet';
616 462 100       1353 $text =~ m(^\s* \d+ \s*$ )x and $item->{item_type} = 'number';
617 462 100       1213 $item->{item_type} or $item->{item_type} = 'text';
618             }
619              
620             sub clone {
621 696     696 1 912 my $node = shift;
622 696         2311 my $clone = {%$node};
623              
624 696         1153 my $children = $node->{children};
625 696         1252 $clone->{children} = [ map { $_->clone } @$children ];
  419         702  
626              
627 696         1927 bless $clone, ref $node;
628             }
629              
630             my $Indent;
631             my $String;
632              
633             sub dump {
634 15     15 1 37 my $node = shift;
635              
636 15         23 $Indent = 0;
637 15         29 $String = '';
638 15         51 $node->_dump;
639 15         131 $String;
640             }
641              
642             sub _dump {
643 1266     1266   1635 my $node = shift;
644 1266         1814 my $type = $node->get_type;
645              
646 1266         2437 $String .= ' ' x $Indent . uc $type . " ";
647              
648 1266         1869 for ($type) {
649 1266 100       2203 /command/ and $String .= $node->_dump_command;
650 1266 100       2146 /code/ and $String .= $node->_dump_code;
651 1266 100       2070 /for/ and $String .= $node->_dump_for;
652 1266 100       2078 /item/ and $String .= $node->_dump_item;
653 1266 100       2124 /list/ and $String .= $node->_dump_list;
654 1266 100       2052 /ordinary/ and $String .= "\n";
655 1266 100       2018 /root/ and $String .= "\n";
656 1266 100       1972 /sequence/ and $String .= $node->_dump_sequence;
657 1266 100       2430 /text/ and $String .= $node->_dump_text;
658 1266 100       2530 /verbatim/ and $String .= $node->_dump_verbatim;
659             }
660              
661 1266         2487 $node->_dump_children;
662 1266         1841 $node->_dump_siblings;
663             }
664              
665             sub _dump_command {
666 65     65   94 my $node = shift;
667 65         126 my $command = $node->get_command;
668 65         126 my $arg = $node->get_arg;
669              
670 65         147 "$command $arg\n";
671             }
672              
673             sub _dump_code {
674 11     11   15 my $node = shift;
675              
676 11         23 my $text = _indent( $node->get_text, 3 );
677 11         28 my $block = "\n{\n$text}\n";
678              
679 11         17 _indent( $block, $Indent );
680             }
681              
682             sub _dump_for {
683 3     3   6 my $node = shift;
684 3         7 my $arg = $node->get_arg;
685 3         6 my $text = _indent( $node->get_text, $Indent + 3 );
686              
687 3         8 "$arg\n$text\n";
688             }
689              
690             sub _dump_item {
691 168     168   218 my $node = shift;
692 168         257 uc $node->get_item_type . "\n";
693             }
694              
695             sub _dump_list {
696 76     76   99 my $node = shift;
697 76         134 uc $node->get_list_type . "\n";
698             }
699              
700             sub _dump_sequence {
701 94     94   122 my $node = shift;
702 94         159 my $letter = $node->get_letter;
703 94 100       169 my $link = $node->is_link ? $node->_dump_target : '';
704              
705 94         205 "$letter$link\n";
706             }
707              
708             sub _dump_text {
709 588     588   824 my $node = shift;
710 588         817 my $text = $node->get_text;
711              
712 588         1083 $text =~ s/([\x80-\xff])/sprintf("\\x%02x", ord($1))/eg;
  12         47  
713              
714 588         929 my $indent = ' ' x ( $Indent + 5 );
715 588         1575 $text =~ s( (?<=\n) (?=.) )($indent)xg;
716 588         1198 "$text\n";
717             }
718              
719             sub _dump_verbatim {
720 6     6   14 my $node = shift;
721 6         14 "\n" . $node->get_text . "\n";
722             }
723              
724             sub _dump_target {
725 28     28   39 my $node = shift;
726 28         46 my $target = $node->get_target;
727 28         53 my $page = $target->{page};
728 28         43 my $section = $target->{section};
729 28         63 " $page / $section";
730             }
731              
732             sub _dump_children {
733 1266     1266   1536 my $node = shift;
734 1266         1695 my $children = $node->get_children;
735 1266 100       2477 $children and DumpList( $children, '{', '}' );
736             }
737              
738             sub _dump_siblings {
739 1266     1266   1528 my $node = shift;
740 1266         1749 my $siblings = $node->get_siblings;
741 1266 100       2570 $siblings and DumpList( $siblings, '[', ']' );
742             }
743              
744             sub DumpList {
745 826     826 0 1388 my ( $nodes, $open, $close ) = @_;
746              
747 826         1365 $String .= ' ' x $Indent . "$open\n";
748 826         970 $Indent += 3;
749              
750 826         1191 for my $node (@$nodes) {
751 1251         1920 $node->_dump;
752             }
753              
754 826         992 $Indent -= 3;
755 826         1602 $String .= ' ' x $Indent . "$close\n";
756             }
757              
758             sub _indent {
759 25     25   48 my ( $text, $spaces ) = @_;
760 25         38 my $indent = ' ' x $spaces;
761 25         167 $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 342 my ( $package, $filename ) = @_;
775              
776 150         324 $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__