File Coverage

blib/lib/Pod/MultiLang.pm
Criterion Covered Total %
statement 102 160 63.7
branch 31 66 46.9
condition 1 6 16.6
subroutine 19 20 95.0
pod 8 8 100.0
total 161 260 61.9


line stmt bran cond sub pod time code
1             ## ----------------------------------------------------------------------------
2             # Pod::MultiLang::Html
3             # -----------------------------------------------------------------------------
4             # Mastering programed by YAMASHINA Hio
5             #
6             # Copyright YAMASHINA Hio
7             # -----------------------------------------------------------------------------
8             # $Id: /perl/Pod-MultiLang/lib/Pod/MultiLang.pm 624 2008-02-06T09:15:55.362158Z hio $
9             # -----------------------------------------------------------------------------
10             package Pod::MultiLang;
11 8     8   20251 use strict;
  8         69  
  8         311  
12 8     8   42 use warnings;
  8         19  
  8         322  
13              
14 8     8   45 use vars qw($VERSION);
  8         107  
  8         631  
15             $VERSION = '0.14';
16              
17 8     8   47 use Pod::Parser;
  8         21  
  8         437  
18 8     8   51 use Pod::InputObjects;
  8         13  
  8         311  
19             our @ISA = qw(Pod::Parser);
20 8     8   308 use Carp;
  8         14  
  8         741  
21              
22             use constant
23             {
24 8         2190 PARA_VERBATIM => 1,
25             PARA_TEXTBLOCK => 2,
26             PARA_HEAD => 3,
27             PARA_OVER => 4,
28             PARA_BACK => 5,
29             PARA_ITEM => 6,
30             PARA_BEGIN => 7,
31             PARA_END => 8,
32             PARA_FOR => 9,
33             PARA_ENCODING => 10,
34             PARA_POD => 11,
35             PARA_CUT => 12,
36 8     8   49 };
  8         95  
37             use constant
38             {
39 8         1082 PARAINFO_TYPE => 0,
40             PARAINFO_PARAOBJ => 1,
41             # =head
42             PARAINFO_CONTENT => 2,
43             PARAINFO_ID => 3,
44             PARAINFO_HEADSIZE => 4,
45             # =over,item,back
46             PARAINFO_LISTTYPE => 2,
47             #PARAINFO_ID => 3,
48 8     8   45 };
  8         24  
49             use constant
50             {
51 8         582 LISTTYPE_UL => 'ul',
52             LISTTYPE_OL => 'ol',
53             LISTTYPE_DL => 'dl',
54 8     8   45 };
  8         14  
55             use constant
56             {
57 8         17266 DEFAULT_LANG => 'en',
58             LANGS => 'en',
59 8     8   41 };
  8         16  
60              
61              
62             # -----------------------------------------------------------------------------
63             # new
64             #
65             sub new
66             {
67 78     78 1 311 my $pkg = shift;
68 78         1810 my $this = $pkg->SUPER::new(@_);
69 78         296 my %arg = @_;
70 78 100       333 if( !$arg{langs} )
    100          
    50          
71             {
72 71         713 $this->{opt_langs} = [split(/[,:]/,LANGS)];
73             }elsif( ref($arg{langs})eq'ARRAY' )
74             {
75 5         45 $this->{opt_langs} = $arg{langs};
76             }elsif( !ref($arg{langs}) )
77             {
78 2         26 $this->{opt_langs} = [split(/[,:]/,$arg{langs})];
79             }else
80             {
81 0         0 croak "invalid langs (is ref, but not ARRAY-ref): [$arg{langs}]";
82             }
83            
84 78         456 $this;
85             }
86              
87             # =============================================================================
88             # Pod::Parser handler.
89             # =============================================================================
90              
91             # -----------------------------------------------------------------------------
92             # begin_pod
93             # initialize pod parsing.
94             #
95             sub begin_pod
96             {
97 78     78 1 164 my ($parser, $command, $paragraph, $line_num) = @_;
98 78         145 $parser->{langs} = [@{$parser->{opt_langs}}];
  78         2239  
99 78         252 $parser->{paras} = [];
100 78         151 $parser->{heads} = [];
101 78         159 $parser->{items} = [];
102            
103 78         182 $parser->{_neststack} = [];
104 78         248 $parser->{_skipblock} = undef;
105             }
106              
107             sub end_pod
108 78     78 1 303 {
109             }
110              
111             # -----------------------------------------------------------------------------
112             # command
113             # parse command paragraph.
114             #
115             sub command
116             {
117 89     89 1 19919 my ($parser, $command, $paragraph, $line_num, $pod_para) = @_;
118 89         565 $paragraph =~ s/^\s+//;
119 89         702 $paragraph =~ s/\s+$//;
120            
121             # skip non-supported begin-end blocks
122             # 対象外の begin-end 間はスキップ
123 89 50       472 if( defined($parser->{_skipblock}) )
124             {
125 0 0 0     0 if( $command eq 'end' && $parser->{_skipblock} eq $paragraph )
126             {
127 0         0 $parser->{_skipblock} = undef;
128             }
129 0         0 return;
130             }
131            
132 89 100       1818 if( $command =~ /^head[1-4]$/ )
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    50          
133             {
134 3         23 my $para = [PARA_HEAD,$pod_para];
135 3         8 push(@{$parser->{paras}},$para);
  3         13  
136 3         12 push(@{$parser->{heads}},$para);
  3         47  
137             }elsif( $command eq 'over' )
138             {
139 0         0 my $para = [PARA_OVER,$pod_para];
140 0         0 push(@{$parser->{_neststack}},[$para]);
  0         0  
141 0         0 push(@{$parser->{paras}},$para);
  0         0  
142             }elsif( $command eq 'back' )
143             {
144 0         0 my $para = [PARA_BACK,$pod_para];
145 0         0 my $info = pop(@{$parser->{_neststack}});
  0         0  
146 0 0       0 if( ref($info) )
147             {
148             #warn "empty =over .. =back, at ".$info->[0][PARAINFO_PARAOBJ]->file_line()."\n";
149 0         0 foreach(@$info)
150             {
151 0         0 $_->[PARAINFO_LISTTYPE] = LISTTYPE_UL;
152             }
153 0         0 $info = LISTTYPE_UL;
154             }
155 0 0       0 if( !defined($info) )
156             {
157 0         0 warn "=back without =over at ".$para->[PARAINFO_PARAOBJ]->file_line()."\n";
158 0         0 $info = LISTTYPE_UL;
159             }
160 0         0 $para->[PARAINFO_LISTTYPE] = $info;
161 0         0 push(@{$parser->{paras}},$para);
  0         0  
162             }elsif( $command eq 'item' )
163             {
164 0         0 my $para = [PARA_ITEM,$pod_para];
165 0 0       0 if( ref($parser->{_neststack}[-1]) )
    0          
    0          
166 0         0 {
167 0         0 $paragraph =~ s/^\s+//;
168 0         0 $paragraph =~ s/\s+$//;
169 0 0       0 my $type = $paragraph eq '*' ? LISTTYPE_UL
    0          
170             : $paragraph =~ /^\d+$/ ? LISTTYPE_OL
171             : LISTTYPE_DL;
172 0         0 foreach(@{$parser->{_neststack}[-1]})
  0         0  
173             {
174 0         0 $_->[PARAINFO_LISTTYPE] = $type;
175             }
176 0         0 $parser->{_neststack}[-1] = $type;
177             }elsif( !@{$parser->{_neststack}} )
178             {
179 0         0 warn "=item without =over at ".$para->[PARAINFO_PARAOBJ]->file_line()."\n";
180 0         0 $paragraph =~ s/^\s+//;
181 0         0 $paragraph =~ s/\s+$//;
182 0 0       0 my $type = $paragraph eq '*' ? LISTTYPE_UL
    0          
183             : $paragraph =~ /^\d+$/ ? LISTTYPE_OL
184             : LISTTYPE_DL;
185 0         0 push(@{$parser->{_neststack}},$type);
  0         0  
186             }elsif( !defined$parser->{_neststack}[-1] )
187             {
188 0         0 warn "undefined item type at ".$para->[PARAINFO_PARAOBJ]->file_line()."\n";
189 0         0 $parser->{_neststack}[-1] = LISTTYPE_UL;
190             }
191 0         0 $para->[PARAINFO_LISTTYPE] = $parser->{_neststack}[-1];
192 0         0 push(@{$parser->{paras}},$para);
  0         0  
193 0         0 push(@{$parser->{items}},$para);
  0         0  
194             }elsif( $command eq 'begin' )
195             {
196 2         19 my $para = [PARA_BEGIN,$pod_para];
197 2         14 $para->[PARAINFO_CONTENT] = $paragraph;
198 2         9 push(@{$parser->{paras}},$para);
  2         17  
199             }elsif( $command eq 'end' )
200             {
201 2         7 my $para = [PARA_END,$pod_para];
202 2         9 $para->[PARAINFO_CONTENT] = $paragraph;
203 2         6 push(@{$parser->{paras}},$para);
  2         59  
204             }elsif( $command eq 'for' )
205             {
206 2         18 my $para = [PARA_FOR,$pod_para];
207 2         14 $para->[PARAINFO_CONTENT] = $paragraph;
208 2         9 push(@{$parser->{paras}},$para);
  2         60  
209             }elsif( $command eq 'encoding' )
210             {
211 2         17 my $para = [PARA_ENCODING,$pod_para];
212 2         17 $para->[PARAINFO_CONTENT] = $paragraph;
213 2         7 push(@{$parser->{paras}},$para);
  2         40  
214             }elsif( $command eq 'cut' )
215             {
216 0         0 my $para = [PARA_CUT,$pod_para];
217 0         0 $para->[PARAINFO_CONTENT] = $paragraph;
218 0         0 push(@{$parser->{paras}},$para);
  0         0  
219             }elsif( $command eq 'pod' )
220             {
221 78         451 my $para = [PARA_POD,$pod_para];
222 78         276 $para->[PARAINFO_CONTENT] = $paragraph;
223 78         159 push(@{$parser->{paras}},$para);
  78         2655  
224             }else
225             {
226 0         0 warn "unknown command [$command] [$paragraph]";
227             }
228             }
229              
230             # -----------------------------------------------------------------------------
231             # verbatim
232             # parse verbatim paragraph.
233             #
234             sub verbatim
235             {
236 0     0 1 0 my ($parser, $paragraph, $line_num, $pod_para, ) = @_;
237            
238 0 0       0 if( defined($parser->{_skipblock}) )
239             {
240 0         0 return;
241             }
242            
243 0         0 push(@{$parser->{paras}},[PARA_VERBATIM,$pod_para]);
  0         0  
244             }
245              
246             # -----------------------------------------------------------------------------
247             # textblock
248             # parse normal (text) paragraph.
249             #
250             sub textblock
251             {
252 77     77 1 7302 my ($parser, $paragraph, $line_num, $pod_para) = @_;
253            
254 77 50       451 if( defined($parser->{_skipblock}) )
255             {
256 0         0 return;
257             }
258            
259 77         389 my $para = [PARA_TEXTBLOCK,$pod_para];
260 77         150 push(@{$parser->{paras}},$para);
  77         249  
261 77         2854 return;
262             }
263              
264             # =============================================================================
265             # UTILITY METHODS
266             # =============================================================================
267              
268             # -----------------------------------------------------------------------------
269             # $label = $parser->makelinktext($lang,$text,$name,$sec);
270             # make link label.
271             #
272             sub makelinktext
273             {
274 4     4 1 12 my ($parser,$lang,$text,$name,$sec) = @_;
275 4 50 33     17 if( !defined($text) || $text eq '' )
276             {
277 4 50       12 if( $lang eq 'en' )
278             {
279 4 100       22 $text = $name ? !$sec ? $name : "\"$sec\" in $name" : "\"$sec\"";
    50          
280             }else
281             {
282 0         0 my $dict = 'Pod::MultiLang::Dict';
283 0         0 $text = $dict->make_linktext($lang,$name,$sec);
284             }
285             }
286 4         20 return $text;
287             }
288              
289             # -----------------------------------------------------------------------------
290             # ($lang,$text) = $parser->parseLang($text);
291             # parse J<> sequence.
292             # J<> の中身を解析.
293             #
294             sub parseLang
295             {
296 2     2 1 3 my $text = $_[1];
297 2 50       10 defined($text) or return ('','');
298 2 50       17 my $lang = $text =~ s,^\s*(\w+)\s*[/;]\s*,, ? $1 : '';
299 2         10 ($lang,$text);
300             }
301              
302             # -----------------------------------------------------------------------------
303             # $out = $this->_from_to($src,$pos);
304             # charset conversion.
305             # 文字セット変換
306             #
307             sub _from_to
308             {
309 195     195   383 my $this = shift;
310 195         392 my $text = shift;
311 195         275 my $pos = shift;
312            
313 195 100       736 if( $this->{_in_charset} ne $this->{_out_charset} )
314             {
315 8     8   8800 use Encode ();
  8         150980  
  8         761  
316 120         373 my $flag = &Encode::FB_HTMLCREF;# | &Encode::FB_WARN;
317 120         994 $text = Encode::encode($this->{_out_charset}, Encode::decode($this->{_in_charset}, $text), $flag);
318             #$text = encode($this->{_out_charset}, decode($this->{_in_charset}, $text));
319             #$text = Unicode::Japanese->new($text, "utf8")->euc;
320             #$text =~ s/([^ -~])/sprintf("[%02x]",unpack("C",$1))/ge;
321             }
322 195         42572 $text;
323             }
324              
325             1;
326             __END__