File Coverage

blib/lib/Pod/MultiLang/Pod.pm
Criterion Covered Total %
statement 270 379 71.2
branch 76 170 44.7
condition 40 85 47.0
subroutine 28 31 90.3
pod 11 11 100.0
total 425 676 62.8


line stmt bran cond sub pod time code
1             ## ----------------------------------------------------------------------------
2             # Pod::MultiLang::Pod
3             # -----------------------------------------------------------------------------
4             # Mastering programed by YAMASHINA Hio
5             #
6             # Copyright 2003 YMIRLINK,Inc.
7             # -----------------------------------------------------------------------------
8             # $Id: /perl/Pod-MultiLang/lib/Pod/MultiLang/Pod.pm 624 2008-02-06T09:15:55.362158Z hio $
9             # -----------------------------------------------------------------------------
10             package Pod::MultiLang::Pod;
11 3     3   76955 use strict;
  3         9  
  3         179  
12              
13 3     3   2744 use File::Spec::Functions;
  3         7729  
  3         288  
14 3     3   2571 use Hash::Util qw(lock_keys);
  3         8067  
  3         19  
15 3     3   270 use Cwd;
  3         6  
  3         191  
16 3     3   2652 use UNIVERSAL qw(isa can);
  3         38  
  3         15  
17 3     3   1464 use List::Util qw(first);
  3         5  
  3         267  
18 3     3   2325 use Pod::ParseLink qw(parselink);
  3         2521  
  3         169  
19              
20 3     3   1760 use Pod::MultiLang;
  3         11  
  3         185  
21 3     3   1777 use Pod::MultiLang::Dict;
  3         9  
  3         55  
22             our @ISA = qw(Pod::MultiLang Pod::Parser);
23             use constant
24             {
25 3         559 PARA_VERBATIM => 1,
26             PARA_TEXTBLOCK => 2,
27             PARA_HEAD => 3,
28             PARA_OVER => 4,
29             PARA_BACK => 5,
30             PARA_ITEM => 6,
31             PARA_BEGIN => 7,
32             PARA_END => 8,
33             PARA_FOR => 9,
34             PARA_ENCODING => 10,
35             PARA_POD => 11,
36             PARA_CUT => 12,
37 3     3   207 };
  3         6  
38             use constant
39             {
40 3         277 PARAINFO_TYPE => 0,
41             PARAINFO_PARAOBJ => 1,
42             # =head
43             PARAINFO_CONTENT => 2,
44             PARAINFO_ID => 3,
45             PARAINFO_HEADSIZE => 4,
46             # =over,item,back
47             PARAINFO_LISTTYPE => 2,
48             #PARAINFO_ID => 3,
49 3     3   17 };
  3         6  
50             use constant
51             {
52 3         200 DEFAULT_LANG => 'en',
53 3     3   16 };
  3         4  
54             use constant
55             {
56 3         11306 VERBOSE_NONE => 0,
57             VERBOSE_ERROR => 10,
58             VERBOSE_NOLINK => 20,
59             VERBOSE_WARN => 30,
60             VERBOSE_DEFAULT => 50,
61             VERBOSE_FINDLINK => 90,
62             VERBOSE_VERBOSE => 80,
63             VERBOSE_DEBUG => 95,
64             VERBOSE_FULL => 100,
65 3     3   15 };
  3         6  
66              
67             sub verbmsg
68             {
69 0     0 1 0 my ($parser,$level) = @_;
70 0 0       0 if( $parser->{_verbose}>=$level )
71             {
72 0         0 my $verbout = $parser->{_verbout};
73 0         0 print $verbout @_[2..$#_];
74             }
75             }
76              
77             # -----------------------------------------------------------------------------
78             # $parser->_map_head_word($ptree)
79             # head のテキストに基本訳を付ける
80             #
81             sub _map_head_word
82             {
83 2     2   38 my ($parser,$ptree) = @_;
84 2 50       14 ref($ptree) or $ptree = Pod::Paragraph->new(-text=>$ptree);
85            
86 2         10 my $text = $ptree->text();
87 2         6579 $text =~ s/^\s+//;
88 2         16 $text =~ s/\s+$//;
89            
90 2         39 my @text = Pod::MultiLang::Dict->find_word($parser->{langs},$text);
91 2         5 my $num_found = grep{defined($_)}@text;
  2         7  
92 2 50       6 if( $num_found==0 )
93             {
94 2         6 return $ptree;
95             }
96 0 0       0 if( $num_found==1 )
97             {
98 0         0 my $i = 0;
99 0         0 foreach(@text)
100             {
101 0 0 0     0 if( defined($_) && $parser->{langs}[$i] && $parser->{langs}[$i]eq'en' )
      0        
102             {
103             # default only.
104 0         0 return $ptree;
105             }
106 0         0 ++$i;
107             }
108             }
109 0         0 my $i=0;
110 0         0 my $result = $text;
111 0         0 foreach(@text)
112             {
113 0 0       0 if( defined($_) )
114             {
115 0         0 $result .= "\nJ<$parser->{langs}[$i];$_>";
116             }
117 0         0 ++$i;
118             }
119 0         0 $ptree->text($result);
120 0         0 $ptree;
121             }
122              
123             # -----------------------------------------------------------------------------
124             # new
125             # コンストラクタ
126             #
127             sub new
128             {
129 35     35 1 92748 my $pkg = shift;
130 35 50       352 ref($pkg) and $pkg = ref($pkg);
131 35 50 33     433 my %arg = @_&&ref($_[0])eq'HASH'?%{$_[0]}:@_;
  35         171  
132            
133             # SUPER クラスを使ってインスタンスを生成.
134             #
135 35 100       90 my @passarg = map{exists($arg{$_})?($_=>$arg{$_}):()}qw(langs);
  35         153  
136 35         505 my $parser = $pkg->SUPER::new(@passarg);
137            
138             # 見出し変換辞書のロード
139             #
140 35 100       154 exists($arg{langs}) and Pod::MultiLang::Dict->load_dict($arg{langs});
141            
142             # 設定を記録
143             #
144 35         430 $parser->{opt_use_index} = 1;
145 35   50     286 $parser->{opt_default_lang} = $arg{default_lang} || DEFAULT_LANG;
146 35   100     1126 $parser->{_in_charset} = $arg{in_charset} || 'utf-8';
147 35   100     189 $parser->{_out_charset} = $arg{out_charset} || 'utf-8';
148 35         82 $parser->{_langstack} = undef;
149 35         99 $parser->{linkcache} = {};
150            
151 35         545 @$parser{qw(_verbose _verbout
152             langs _expandlangs _default_lang _fetchlangs
153             _langstack _neststack _skipblock _iseqstack
154             paras heads items
155             _cssprefix
156             out_outfile out_outdir out_topdir
157             )} = ();
158 35         310 @$parser{qw( _INFILE _OUTFILE _PARSEOPTS _CUTTING
159             _INPUT _OUTPUT _CALLBACKS _TOP_STREAM _ERRORSUB
160             _INPUT_STREAMS
161             )} = ();
162             #_SELECTED_SECTIONS
163             #lock_keys(%$parser);
164            
165 35         177 $parser;
166             }
167              
168             # -----------------------------------------------------------------------------
169             # begin_pod
170             # 初期化
171             #
172             sub begin_pod
173             {
174 35     35 1 2039 my $parser = shift;
175 35         209 $parser->SUPER::begin_pod(@_);
176            
177 35         72 $parser->{_verbose} = VERBOSE_DEFAULT;
178 35         94 $parser->{_verbout} = \*STDERR;
179 35         65 $parser->{_expandlangs} = undef;
180 35         74 $parser->{_default_lang} = $parser->{opt_default_lang};
181 35         105 $parser->{_fetchlangs} = undef;
182 35         90 $parser->{_langstack} = [undef];
183            
184 35         1419 my $outfile = $parser->output_file();
185 35 50       6694 file_name_is_absolute($outfile) or $outfile = File::Spec->rel2abs($outfile);
186 35         3731 my $outdir = (File::Spec->splitpath($outfile))[1];
187 35         114 $parser->{out_outfile} = $outfile;
188 35         68 $parser->{out_outdir} = $outdir;
189 35   50     333850 $parser->{out_topdir} = File::Spec->abs2rel(cwd(),$outdir)||'';
190            
191             # ディレクトリは末尾/付きに正規化
192 35         343 foreach(@$parser{qw(out_topdir out_outdir)})
193             {
194 70 100 66     1324 defined($_) && !m/\/$/ and $_.='/';
195             }
196            
197 35 50       3628 if( $parser->{_verbose}>=VERBOSE_FULL )
198             {
199 0         0 my $out = $$parser{_verbout};
200 0         0 print $out $parser->input_file()."\n";
201 0         0 print $out "scan...\n";
202             }
203             }
204              
205             # -----------------------------------------------------------------------------
206             # interior_sequence
207             # 装飾符号の展開
208             #
209             sub interior_sequence
210             {
211 1     1 1 5 my ($parser, $seq_command, $seq_argument,$seq_obj) = @_;
212 1         10 my $ldelim = $seq_obj->left_delimiter();
213 1         14 my $rdelim = $seq_obj->right_delimiter();
214            
215 1 50       19 if( $seq_command eq 'I' )
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
216             {
217             }elsif( $seq_command eq 'B' )
218             {
219             }elsif( $seq_command eq 'C' )
220             {
221             }elsif( $seq_command eq 'L' )
222             {
223 0         0 die "L<> not processed here..";
224             }elsif( $seq_command eq 'E' )
225             {
226             }elsif( $seq_command eq 'F' )
227             {
228             }elsif( $seq_command eq 'S' )
229             {
230             }elsif( $seq_command eq 'X' )
231             {
232             }elsif( $seq_command eq 'Z' )
233             {
234             }elsif( $seq_command eq 'J' )
235             {
236 0         0 die "J<> not processed here..";
237             }
238 1         6 return "$seq_command$ldelim$seq_argument$rdelim";
239             }
240              
241             # -----------------------------------------------------------------------------
242             # buildtext
243             # paraobj から text を生成
244             #
245             sub buildtext
246             {
247 36     36 1 80 my ($parser,$paraobj) = @_;
248            
249 36         51 my $ptree;
250 36 50       277 if( isa($paraobj,'Pod::Paragraph') )
251             {
252 36         6019 $ptree = $parser->parse_text($paraobj->text(),($paraobj->file_line())[1]);
253             }else
254             {
255 0         0 $ptree = $paraobj;
256             }
257            
258             # @list containts [langs..,,no-lang];
259 36         195 my @list = $parser->parse_mlpod($ptree);
260            
261 36         59 my @text;
262 36         77 for( my $i=0; $i<=$#{$parser->{langs}}; ++$i )
  72         269  
263             {
264 36         83 my $lang = $parser->{langs}[$i];
265 36 100       179 if( defined($list[$i]) )
    50          
266             {
267             # has text for this language.
268             #
269 2         20 push(@text,$list[$i]);
270             }elsif( $parser->{langs}[$i] eq $parser->{_default_lang} )
271             {
272             # no text for this language, but this is original language.
273             #
274 34         276 unshift(@text,$list[-1]);
275             }
276             }
277 36         93 my $ret = join('',map{s/\n(\s*\n)+/\n/g;"$_\n"}grep{/\S/}@text);
  36         193  
  36         274  
  36         1325  
278            
279 36 50       111 if( $ret eq '' )
280             {
281 0 0       0 $ret = (grep{defined($_)&&/\S/} @list[-1,0..$#list-1],'Z<>')[0];
  0         0  
282             }
283 36         1004 $ret;
284             }
285 0 0   0   0 sub _a2s{ join('-',map{defined($_)?"[$_]":'{undef}'}@_) }
  0         0  
286              
287             # -----------------------------------------------------------------------------
288             # $idx = $parser->_find_lang_index($lang);
289             # if not found, returns undef.
290             #
291             sub _find_lang_index
292             {
293 43     43   164 my ($this,$lang) = @_;
294 43         172 for( my $i=0; $i<=$#{$this->{langs}}; ++$i )
  49         197  
295             {
296 43 100       164 if( $this->{langs}[$i] eq $lang )
297             {
298 37         304 return $i;
299             }
300             }
301 6         97 undef;
302             }
303              
304             # -----------------------------------------------------------------------------
305             # $ret = $parser->on_mlpod_plain($text);
306             #
307             sub on_mlpod_plain
308             {
309 45     45 1 65 my $parser = shift;
310 45         78 my $text = shift;
311 45         134 $text;
312             }
313             # -----------------------------------------------------------------------------
314             # $ret = $parser->on_mlpod_link($parselink,$seq_obj);
315             #
316             sub on_mlpod_link
317             {
318 1     1 1 2 my $parser = shift;
319 1         2 my $parselink = shift;
320 1         2 my $seq_obj = shift;
321 1         3 my ($text, $inferred, $name, $section, $type) = @$parselink;
322            
323 1         8 my $seq_command = 'L';
324 1         5 my $seq_argument = "";
325 1 50       4 defined($text) and $seq_argument .= "$text|";
326 1 50       3 defined($name) and $seq_argument .= "$name";
327 1 50       10 defined($section) and $seq_argument .= "/$section";
328            
329 1         6 my $ldelim = $seq_obj->left_delimiter();
330 1         4 my $rdelim = $seq_obj->right_delimiter();
331 1         4 return "$seq_command$ldelim$seq_argument$rdelim";
332             }
333              
334             # -----------------------------------------------------------------------------
335             # @ret = $parser->parse_mlpod($ptree,$inlang);
336             # Pod::Parser, InteriorSequence 等の処理.
337             # @ret: 言語毎の変換結果.
338             #
339             sub parse_mlpod
340             {
341 42     42 1 132 my ($parser,$ptree,$inlang) = @_;
342              
343             # @ret[0..$#langs]: for that lang.
344             # $ret[-1], $ret[@langs]: fallback.
345 42         68 my @ret = ((undef)x@{$parser->{langs}},'');
  42         279  
346              
347             # find index for default lang.
348 42   50     283 my $idx_default_lang = $parser->_find_lang_index($parser->{_default_lang})||0;
349            
350 42 50       225 if( can($ptree,'parse_tree') )
351             {
352 42         173 $ptree = $ptree->parse_tree();
353             }
354 42 0       462 my @children = can($ptree,'children')?$ptree->children():isa($ptree,'ARRAY')?@$ptree:die "unknown object : $ptree";
    50          
355             #print STDERR "in: @{[scalar@children]} ",_a2s(@children),"\n";
356 42         110 foreach (@children)
357             {
358 51 100       147 if( !ref($_) )
359             {
360             # plain text.
361 45         193 $ret[-1] .= $parser->on_mlpod_plain($_);
362 45         119 next;
363             }
364 6         37 my $cmd_name = $_->cmd_name();
365 6 100 100     51 if( $cmd_name ne 'J' && $cmd_name ne 'L' )
    100          
366             {
367             # normal iseq.
368             #print STDERR "normal iseq\n";
369            
370             # iseq の中身を mlpod 分解.
371             #
372 1         25 my @child = $parser->parse_mlpod($_->parse_tree());
373             #print STDERR" child : $#child "._a2s(@child)."\n";
374            
375             # default_lang が未定義だったら, 言語指定なし部分を充てる.
376             #
377 1 50 33     24 if( !defined($child[$idx_default_lang])
  1         14  
378 1         7 && grep{defined($_)} @child[0..$#{$parser->{langs}}] )
379             {
380 0         0 $child[$idx_default_lang] = $child[-1];
381             }
382             # 装飾符号の展開.
383             #
384 1         18 my $cmd_name = $_->cmd_name();
385 1         10 for( my $i=0; $i<=$#child; ++$i )
386             {
387 2 100       9 if( defined($child[$i]) )
388             {
389 1         10 my $ret = $parser->interior_sequence($cmd_name,$child[$i],$_);
390 1 50       9 defined($ret[$i]) or $ret[$i] = '';
391 1         6 $ret[$i] .= $ret;
392             }
393             }
394             }elsif( $cmd_name eq 'L' )
395             {
396             # link iseq.
397             #print STDERR "link iseq\n";
398             #
399 1         29 my $content = $_->raw_text();
400 1         6 $content =~ s/^L\<+\s*//;
401 1         12 $content =~ s/\s*\>+$//;
402 1         13 my ($text, $inferred, $name, $section, $type) = parselink($content);
403 1 50 33     93 if( !$section && $name =~ / / )
404             {
405 0         0 $section = $name;
406 0         0 $name = '';
407             }
408            
409 1 50       8 if( $content !~ /J\
410             {
411             # if there is no J<> sequences.
412 0         0 my $parselink = [$text,$inferred,$name,$section,$type];
413 0         0 my $link = $parser->on_mlpod_link($parselink,$_);
414 0 0       0 defined($ret[-1]) or $ret[-1] = '';
415 0         0 $ret[-1] .= $link;
416 0         0 next;
417             }
418            
419 1         11 my $line = ($_->file_line())[1];
420 1         3 foreach($text, $name, $section)
421             {
422 3 100       8 if( !defined($_) )
423             {
424 2         4 $_ = [(undef)x$#ret];
425 2         3 next;
426             }
427 1         123 my $ptree = $parser->parse_text($_,$line);
428 1         11 my @child = $parser->parse_mlpod($ptree);
429             # default_lang が未定義だったら, 言語指定なし部分を充てる.
430             # (全部未定義なら必要ない)
431 1 50 33     18 if( defined($idx_default_lang)
  0   33     0  
432             && !defined($child[$idx_default_lang])
433 0         0 && grep{defined($_)}@child[0..$#{$parser->{langs}}] )
434             {
435 0         0 $child[$idx_default_lang] = $child[-1];
436             }
437 1         2 foreach(grep{defined($_)}@child)
  2         6  
438             {
439 2         5 s/^\s+//;
440 2         15 s/\s+$//;
441             }
442 1         37 $_ = \@child;
443             }
444              
445             # 装飾符号の展開.
446             # expand interior sequences.
447             #
448 1         6 my $cmd_name = $_->cmd_name();
449 1   33     5 my $lang = $parser->{_langstack}[-1]||$parser->{_default_lang};
450 1         4 my $idx = $parser->_find_lang_index($lang);
451 1 50       4 defined($idx) or $idx = $idx_default_lang;
452              
453             my $select_proper_text = sub{
454 3     3   4 my $text1 = shift;
455 3         4 my $text2 = shift;
456 3 100 66     31 if( defined($text1) && $text1 ne '' )
    50 33        
    50 33        
457             {
458 1         3 $text1;
459             }elsif( defined($text2) && $text2 ne '' )
460             {
461 0         0 $text2;
462             }elsif( defined($text1) || defined($text2) )
463             {
464 0         0 '';
465             }else
466             {
467 2         5 undef;
468             }
469 1         4 };
470 1         3 my $text_lang = $text->[$idx];
471 1         2 my $text_def = $text->[$idx_default_lang];
472 1         9 my $text_sel = $select_proper_text->($text_lang, $text_def);
473              
474 1         2 my $name_lang = $name->[$idx];
475 1         2 my $name_def = $name->[$idx_default_lang];
476 1         3 my $name_sel = $select_proper_text->($name_lang, $name_def);
477              
478 1         3 my $section_lang = $section->[$idx];
479 1         2 my $section_def = $$section[$idx_default_lang];
480 1         3 my $section_sel = $select_proper_text->($section_lang, $section_def);
481            
482 1         3 my $parselink = [$text_sel,$inferred,$name_sel,$section_sel,$type];
483 1         6 my $link = $parser->on_mlpod_link($parselink,$_);
484 1 50       5 defined($ret[-1]) or $ret[-1] = '';
485 1         21 $ret[-1] .= $link;
486             # if cmd_name eq 'L'
487             }else
488             {
489             # lang iseq.
490             #
491 4         10 my $iseq = $_;
492 4   50     70 my $first = ($iseq->parse_tree()->children())[0] || '';
493 4 50       10 push(@{$parser->{_langstack}},$first=~/^\s*(\w+)\s*[\/;]/?$1:$parser->{_langstack}[-1]);
  4         45  
494 4         88 my @child = $parser->parse_mlpod($iseq->parse_tree());
495 4         8 pop(@{$parser->{_langstack}});
  4         10  
496 4         23 $child[-1] =~ s,^\s*(\w+)\s*[/;]\s*,,;
497 4         19 my $lang = $1;
498 4 50       12 if( !defined($lang) )
499             {
500 0         0 $parser->verbmsg(VERBOSE_ERROR,"no lang in J<>, use default-lang [$parser->{_default_lang}] at ".$iseq->file_line()."\n");
501 0         0 $lang = $parser->{_default_lang};
502             }
503 4         14 for( my $i=0; $i<=$#{$parser->{langs}}; ++$i )
  5         20  
504             {
505 4 100       16 $parser->{langs}[$i] ne $lang and next;
506 3         13 $ret[$i] .= $child[-1];
507 3         12 last;
508             }
509             #print STDERR " iseq: $#ret ",_a2s(@ret),"\n";
510             }
511             }
512 42 100       376 $ret[-1]=~/\S/ or $ret[-1]='';
513             #print "out: @{[scalar@ret]} ",_a2s(@ret),"\n";
514 42         219 @ret;
515             }
516              
517             # -----------------------------------------------------------------------------
518             # end_pod
519             # at end of parsing pod.
520             # build html and output it.
521             #
522             sub end_pod
523             {
524 35     35 1 320 my $parser = shift;
525 35         280 my ($command, $paragraph, $line_num) = @_;
526 35         394 $parser->SUPER::end_pod(@_);
527            
528 35 50       61 if( !@{$parser->{paras}} )
  35         216  
529             {
530 0         0 warn "input has no paragraphs";
531             }
532            
533 35         227 $parser->rebuild();
534 35         237 $parser->output_pod();
535             }
536              
537             # -----------------------------------------------------------------------------
538             # rebuild
539             # build infomations needed for html.
540             #
541             sub rebuild
542             {
543 35     35 1 149 my ($parser, $command, $paragraph, $line_num) = @_;
544            
545 35 50       148 if( $parser->{_verbose}>=VERBOSE_FULL )
546             {
547 0         0 my $out = $$parser{_verbout};
548 0         0 print $out "scan done, rebuild...\n";
549             }
550            
551             # build indices from "head"s.
552             #
553 35         56 foreach (@{$parser->{heads}})
  35         141  
554             {
555 2         5 my ($paraobj) = $$_[PARAINFO_PARAOBJ];
556            
557 2 50       253 if( $paraobj->text() !~ /[^\w\s&]/ )
558             {
559 2         410 $paraobj = $parser->_map_head_word($paraobj);
560 2         6 $_->[PARAINFO_PARAOBJ] = $paraobj;
561             }
562            
563 2         14 $_->[PARAINFO_CONTENT] = $parser->buildtext($paraobj);
564 2   50     24 $_->[PARAINFO_HEADSIZE] = ($paraobj->cmd_name()=~/(\d)/)[0]||0;
565            
566 2         8 $_->[PARAINFO_ID] = q/id is not used/;
567             }
568            
569             # build indices from "item"s too.
570             #
571 35         55 foreach (@{$parser->{items}})
  35         1232  
572             {
573 0         0 my ($paraobj,$listtype) = @$_[PARAINFO_PARAOBJ,PARAINFO_LISTTYPE];
574            
575 0 0       0 $listtype ne 'dl' and next;
576            
577 0 0       0 if( $paraobj->text() !~ /[^\w\s&]/ )
578             {
579 0         0 $paraobj = $parser->_map_head_word($paraobj);
580 0         0 $_->[PARAINFO_PARAOBJ] = $paraobj;
581             }
582            
583 0         0 $_->[PARAINFO_ID] = q/id is not used/;
584             }
585             }
586              
587             # -----------------------------------------------------------------------------
588             # output_pod
589             # podを出力
590             #
591             sub output_pod
592             {
593 35     35 1 79 my ($parser, $command, $paragraph, $line_num) = @_;
594            
595 35         365 my $out_fh = $parser->output_handle();
596            
597 35 50       166 if( $parser->{_verbose}>=VERBOSE_FULL )
598             {
599 0         0 $parser->vermbsg(VERBOSE_FULL,"ok, output...\n");
600             }
601            
602             #binmode($out_fh,":encoding($parser->{_out_charset})");
603             #print defined($out_fh)?"[$out_fh]\n":"{undef}\n";
604 35         1035 binmode($out_fh,":bytes");
605            
606             # 出力開始
607             #
608            
609             # 本文の出力.
610             #
611 35         152 my $in_item = 0;
612 35         134 my $first_item = 1;
613 35         90 my @verbpack;
614             my @blockstack;
615 3     3   28 use constant {STK_PARAOBJ=>0,STK_BEHAVIOR=>1,};
  3         7  
  3         279  
616 3     3   14 use constant {BHV_NONE=>'none',BHV_NORMAL=>'normal',BHV_VERBATIM=>'verbatim',BHV_IGNORE=>'ignore'};
  3         5  
  3         4317  
617            
618 35         65 foreach (@{$parser->{paras}})
  35         115  
619             {
620 80         830 my ($paratype,$paraobj) = @$_[PARAINFO_TYPE,PARAINFO_PARAOBJ];
621 80         222 $parser->{_iseqstack} = [];
622            
623             # ignore 状態の確認
624             #
625 80 50       237 if( grep{$_->[STK_BEHAVIOR]eq BHV_IGNORE}@blockstack )
  0         0  
626             {
627             #print $out_fh " in ignore ...\n";
628 0 0 0     0 if( $paratype==PARA_END
629             && $_->[PARAINFO_CONTENT] eq $blockstack[-1]->[STK_PARAOBJ][PARAINFO_CONTENT] )
630             {
631 0         0 my $fin = pop(@blockstack);
632 0         0 my $mode = $_->[PARAINFO_CONTENT];
633 0         0 my $outtext = "";
634 0         0 print $out_fh $parser->_from_to($outtext);
635             }
636 0         0 next;
637             }
638            
639             # 連続する verbose の連結処理.
640             #
641 80 0 0 0   1208 my $blk = first{(ref($_)||'')eq'ARRAY'&&$$_[STK_BEHAVIOR]ne BHV_IGNORE}reverse @blockstack;
  0         0  
642 80 50 66     1350 if( $paratype==PARA_VERBATIM || ($paratype!=PARA_END&&$blk&&$blk->[STK_BEHAVIOR]eq BHV_VERBATIM) )
    50 33        
      33        
643             {
644 0         0 my $text = $paraobj->text();
645 0         0 $text = $parser->_from_to($text);
646 0 0       0 $text !~ /^\n*$/ and push(@verbpack,$text);
647 0         0 next;
648             }elsif( @verbpack )
649             {
650 0         0 my $text = join('',@verbpack);
651 0         0 $text =~ s/\s*$//;
652 0 0       0 if( $text !~ /^\n*$/ )
653             {
654 0         0 $text =~ s/\n+$/\n/;
655 0         0 my $outtext = "$text\n\n";
656 0         0 $outtext = $parser->_from_to($outtext);
657 0         0 print $out_fh $outtext;
658             }
659 0         0 @verbpack = ();
660             }
661            
662             # 普通に出力処理.
663             # $outtext には _from_to 済みのテキストを追加.
664             #
665 80         413 my $outtext;
666 80 100 100     1218 if( $paratype==PARA_TEXTBLOCK )
    100 100        
    50 100        
    50 66        
    50 33        
    50          
667             {
668 34         806 my $text = $parser->buildtext($paraobj);
669 34         441 $text = $parser->_from_to($text);
670 34 50       338 $text =~ /^\s*$/ and next;
671 34         94 $outtext = $text."\n";
672             }elsif( $paratype==PARA_HEAD )
673             {
674 2         5 my $text = $_->[PARAINFO_CONTENT];
675 2         18 my $cmd = $paraobj->cmd_name();
676 2         7 $text = $parser->_from_to($text);
677 2         14 $text =~ s/\n(\s*\n)+/\n/g;
678 2         5 $outtext = "=$cmd $text\n";
679             }elsif( $paratype==PARA_OVER )
680             {
681 0         0 $outtext = $paraobj->raw_text();
682            
683 0         0 my ($type) = $_->[PARAINFO_LISTTYPE];
684 0         0 $first_item = 1;
685 0         0 my $stk = [];
686 0         0 $stk->[STK_PARAOBJ] = $_;
687 0         0 $stk->[STK_BEHAVIOR] = BHV_NORMAL;
688 0         0 push(@blockstack,$stk);
689             }elsif( $paratype==PARA_BACK )
690             {
691 0         0 $outtext = '';
692 0 0       0 if( $in_item )
693             {
694 0         0 --$in_item;
695             }
696 0         0 pop(@blockstack);
697            
698 0         0 $outtext .= "=back\n\n";
699             }elsif( $paratype==PARA_ITEM )
700             {
701 0         0 my ($type,$id) = @$_[PARAINFO_LISTTYPE,PARAINFO_ID];
702 0         0 $outtext = '';
703 0 0       0 if( !@blockstack )
704             {
705 0         0 my $stk = [];
706 0         0 $stk->[STK_PARAOBJ] = $type;
707 0         0 $stk->[STK_BEHAVIOR] = BHV_NORMAL;
708 0         0 push(@blockstack,$stk);
709 0         0 $outtext .= "=over\n\n";
710             }
711 0 0 0     0 if( $type eq 'ul' || $type eq 'ol' )
    0          
712             {
713 0         0 $outtext .= "=item ".$parser->buildtext($paraobj)."\n\n";
714             }elsif( $type eq 'dl' )
715             {
716 0         0 my $item = $parser->buildtext($paraobj);
717 0         0 $item =~ s/^\s+//;
718 0         0 $item =~ s/\s+$//;
719 0         0 $item = $parser->_from_to($item);
720 0         0 $outtext .= "=item $item\n\n";
721             }else
722             {
723 0         0 $parser->vermsg(VERBOSE_ERROR,"unknown list type [$type]");
724             }
725 0 0       0 $first_item and undef($first_item),++$in_item;
726             }elsif( $paratype==PARA_BEGIN || $paratype==PARA_END
727             || $paratype==PARA_FOR || $paratype==PARA_ENCODING
728             || $paratype==PARA_POD || $paratype==PARA_CUT )
729             {
730 44         447 my $text = $_->[PARAINFO_CONTENT];
731 44         371 my $cmd = $paraobj->cmd_name();
732 44 100       138 if( $text ne '' )
733             {
734 8         108 $text = $parser->_from_to($text);
735 8         30 $text =~ s/\n(\s*\n)+/\n/g;
736 8         33 $outtext = "=$cmd $text\n\n";
737             }else
738             {
739 36         184 $outtext = "=$cmd\n\n";
740             }
741             }else
742             {
743 0         0 $parser->verbmsg(VERBOSE_ERROR,"what\'s got?? [$paratype]");
744 0         0 next;
745             }
746 80 50       241 if( defined($outtext) )
747             {
748             # $outtext は _from_to 済み.
749 80         343 print $out_fh $outtext;
750             }
751             }
752 35 50       3152 if( @verbpack )
753             {
754 0           my $text = join('',@verbpack);
755 0 0         if( $text !~ /^\n*$/ )
756             {
757 0           my $outtext = "$text\n\n";
758 0           $outtext = $parser->_from_to($outtext);
759 0           print $out_fh $outtext;
760             }
761             }
762            
763             # output done.
764             }
765              
766             # =============================================================================
767             # ユーティリティ関数群
768             # =============================================================================
769              
770             1;
771             __END__