blib/lib/Pod/MultiLang/Html.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 488 | 772 | 63.2 |
branch | 168 | 396 | 42.4 |
condition | 43 | 119 | 36.1 |
subroutine | 37 | 43 | 86.0 |
pod | 18 | 18 | 100.0 |
total | 754 | 1348 | 55.9 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | ## ---------------------------------------------------------------------------- | ||||||
2 | # Pod::MultiLang::Html | ||||||
3 | # ----------------------------------------------------------------------------- | ||||||
4 | # Mastering programed by YAMASHINA Hio | ||||||
5 | # | ||||||
6 | # Copyright 2003 YMIRLINK,Inc. | ||||||
7 | # ----------------------------------------------------------------------------- | ||||||
8 | # $Id: /perl/Pod-MultiLang/lib/Pod/MultiLang/Html.pm 578 2007-12-14T05:15:38.051888Z hio $ | ||||||
9 | # ----------------------------------------------------------------------------- | ||||||
10 | package Pod::MultiLang::Html; | ||||||
11 | 6 | 6 | 155724 | use strict; | |||
6 | 16 | ||||||
6 | 273 | ||||||
12 | 6 | 6 | 34 | use vars qw($VERSION); | |||
6 | 11 | ||||||
6 | 330 | ||||||
13 | BEGIN{ | ||||||
14 | 6 | 6 | 99 | $VERSION = '0.03'; | |||
15 | } | ||||||
16 | |||||||
17 | 6 | 6 | 7081 | use File::Spec::Functions; | |||
6 | 5229 | ||||||
6 | 642 | ||||||
18 | 6 | 6 | 6388 | use Hash::Util qw(lock_keys); | |||
6 | 17028 | ||||||
6 | 45 | ||||||
19 | 6 | 6 | 692 | use Cwd; | |||
6 | 13 | ||||||
6 | 416 | ||||||
20 | 6 | 6 | 6279 | use UNIVERSAL qw(isa can); | |||
6 | 78 | ||||||
6 | 36 | ||||||
21 | 6 | 6 | 5023 | use List::Util qw(first); | |||
6 | 13 | ||||||
6 | 718 | ||||||
22 | 6 | 6 | 5239 | use Pod::ParseLink; | |||
6 | 5005 | ||||||
6 | 311 | ||||||
23 | |||||||
24 | 6 | 6 | 4175 | use Pod::MultiLang; | |||
6 | 21 | ||||||
6 | 301 | ||||||
25 | 6 | 6 | 2192 | use Pod::MultiLang::Dict; | |||
6 | 15 | ||||||
6 | 122 | ||||||
26 | our @ISA = qw(Pod::MultiLang); | ||||||
27 | |||||||
28 | use constant | ||||||
29 | { | ||||||
30 | 6 | 1008 | PARA_VERBATIM => 1, | ||||
31 | PARA_TEXTBLOCK => 2, | ||||||
32 | PARA_HEAD => 3, | ||||||
33 | PARA_OVER => 4, | ||||||
34 | PARA_BACK => 5, | ||||||
35 | PARA_ITEM => 6, | ||||||
36 | PARA_BEGIN => 7, | ||||||
37 | PARA_END => 8, | ||||||
38 | PARA_FOR => 9, | ||||||
39 | PARA_ENCODING => 10, | ||||||
40 | PARA_POD => 11, | ||||||
41 | PARA_CUT => 12, | ||||||
42 | 6 | 6 | 347 | }; | |||
6 | 8 | ||||||
43 | use constant | ||||||
44 | { | ||||||
45 | 6 | 531 | PARAINFO_TYPE => 0, | ||||
46 | PARAINFO_PARAOBJ => 1, | ||||||
47 | # =head | ||||||
48 | PARAINFO_CONTENT => 2, | ||||||
49 | PARAINFO_ID => 3, | ||||||
50 | PARAINFO_HEADSIZE => 4, | ||||||
51 | # =over,item,back | ||||||
52 | PARAINFO_LISTTYPE => 2, | ||||||
53 | #PARAINFO_ID => 3, | ||||||
54 | 6 | 6 | 28 | }; | |||
6 | 11 | ||||||
55 | use constant | ||||||
56 | { | ||||||
57 | 6 | 349 | DEFAULT_LANG => 'en', | ||||
58 | 6 | 6 | 30 | }; | |||
6 | 10 | ||||||
59 | use constant | ||||||
60 | { | ||||||
61 | 6 | 56144 | VERBOSE_NONE => 0, | ||||
62 | VERBOSE_ERROR => 10, | ||||||
63 | VERBOSE_NOLINK => 20, | ||||||
64 | VERBOSE_WARN => 30, | ||||||
65 | VERBOSE_DEFAULT => 50, | ||||||
66 | VERBOSE_FINDLINK => 90, | ||||||
67 | VERBOSE_VERBOSE => 80, | ||||||
68 | VERBOSE_DEBUG => 95, | ||||||
69 | VERBOSE_FULL => 100, | ||||||
70 | 6 | 6 | 31 | }; | |||
6 | 95 | ||||||
71 | |||||||
72 | our $VERBOSE_DEFAULT = VERBOSE_DEFAULT; | ||||||
73 | |||||||
74 | sub verbmsg | ||||||
75 | { | ||||||
76 | 4 | 4 | 1 | 7 | my ($parser,$level) = @_; | ||
77 | 4 | 50 | 23 | if( $parser->{_verbose}>=$level ) | |||
78 | { | ||||||
79 | 0 | 0 | my $verbout = $parser->{_verbout}; | ||||
80 | 0 | 0 | print $verbout @_[2..$#_]; | ||||
81 | } | ||||||
82 | } | ||||||
83 | |||||||
84 | # ----------------------------------------------------------------------------- | ||||||
85 | # makelink | ||||||
86 | # L<> から を作成 | ||||||
87 | # | ||||||
88 | sub makelink | ||||||
89 | { | ||||||
90 | 4 | 4 | 1 | 10 | my ($parser,$lang,$text,$target,$sec,$sec_anchor) = @_; | ||
91 | 4 | 66 | 31 | $sec_anchor ||= $sec; | |||
92 | 4 | 50 | 12 | defined($target) or $target = ''; | |||
93 | |||||||
94 | 4 | 5 | my $link_info; | ||||
95 | |||||||
96 | 4 | 50 | 122 | if( exists($parser->{linkcache}{$target}) ) | |||
50 | |||||||
50 | |||||||
97 | { | ||||||
98 | 0 | 0 | $link_info = $parser->{linkcache}{$target}; | ||||
99 | }elsif( $target eq '' ) | ||||||
100 | { | ||||||
101 | 0 | 0 | $link_info = { | ||||
102 | base => '', | ||||||
103 | path => '', | ||||||
104 | href => '', | ||||||
105 | }; | ||||||
106 | 0 | 0 | $parser->{linkcache}{''} = $link_info; | ||||
107 | }elsif( $target =~ /\(\d+\w?\)$/ ) | ||||||
108 | { | ||||||
109 | # 多分man. 適当に^^; | ||||||
110 | # | ||||||
111 | 0 | 0 | $link_info = { | ||||
112 | base => "man:", | ||||||
113 | path => "$target", | ||||||
114 | href => undef, | ||||||
115 | }; | ||||||
116 | 0 | 0 | $parser->{linkcache}{$target} = $link_info; | ||||
117 | }else | ||||||
118 | { | ||||||
119 | # Pkg/Class.html | ||||||
120 | # Pkg/Pkg-Class.html | ||||||
121 | # Pkg-Class.html | ||||||
122 | # Pkg/Pkg-Class-[\d\.]+.html | ||||||
123 | # Pkg-Class-[\d\.]+.html | ||||||
124 | 4 | 27 | (my $file1 = $target.'.html') =~ s,::,/,g; | ||||
125 | 4 | 18 | (my $file3 = $target.'.html') =~ s,::,-,g; | ||||
126 | 4 | 30 | (my $dir = $file1)=~s,[^/]*$,,; | ||||
127 | 4 | 50 | 469 | my $file2 = $dir ne '' ? $dir.$file3 : undef; | |||
128 | 4 | 7 | my $found; | ||||
129 | 4 | 33 | 16 | my $verbout = $parser->{_verbose}>=VERBOSE_FINDLINK && $parser->{_verbout}; | |||
130 | 4 | 7 | foreach my $poddir(@{$parser->{opt_poddir}}) | ||||
4 | 28 | ||||||
131 | { | ||||||
132 | 0 | 0 | $found = $poddir.$file1; | ||||
133 | 0 | 0 | 0 | -f $found and last; | |||
134 | 0 | 0 | 0 | $parser->{_verbose}>=VERBOSE_FINDLINK and $parser->verbmsg(VERBOSE_FINDLINK,"[$target] ==> x [$found]\n"); | |||
135 | 0 | 0 | 0 | if( defined($file2) ) | |||
136 | { | ||||||
137 | 0 | 0 | $found = $poddir.$file2; | ||||
138 | 0 | 0 | 0 | -f $found and last; | |||
139 | 0 | 0 | 0 | $parser->{_verbose}>=VERBOSE_FINDLINK and $parser->verbmsg(VERBOSE_FINDLINK,"[$target] ==> x [$found]\n"); | |||
140 | } | ||||||
141 | 0 | 0 | $found = $poddir.$file3; | ||||
142 | 0 | 0 | 0 | -f $found and last; | |||
143 | 0 | 0 | 0 | $parser->{_verbose}>=VERBOSE_FINDLINK and $parser->verbmsg(VERBOSE_FINDLINK,"[$target] ==> x [$found]\n"); | |||
144 | 0 | 0 | undef $found; | ||||
145 | } | ||||||
146 | 4 | 50 | 12 | if( $found ) | |||
147 | { | ||||||
148 | 0 | 0 | $link_info = { | ||||
149 | base => $parser->{out_topdir}, | ||||||
150 | path => $found, | ||||||
151 | href => undef, | ||||||
152 | }; | ||||||
153 | 0 | 0 | 0 | $parser->{linkcache}{$target} = $link_info, | |||
154 | $parser->{_verbose}>=VERBOSE_FINDLINK and $parser->verbmsg(VERBOSE_FINDLINK,"[$target] ==> [$found]\n"); | ||||||
155 | }else | ||||||
156 | { | ||||||
157 | # not found. | ||||||
158 | # | ||||||
159 | 4 | 13 | my $missing_base; | ||||
160 | 4 | 50 | 33 | 40 | if( defined($parser->{opt_missing_poddir}) && $target=~/^perl\w*$/ ) | ||
50 | 33 | ||||||
100 | |||||||
161 | { | ||||||
162 | 0 | 0 | $missing_base = $parser->{opt_missing_poddir}; | ||||
163 | }elsif( defined($parser->{opt_missing_pragmadir}) && $target =~ /^[a-z]/ ) | ||||||
164 | { | ||||||
165 | 0 | 0 | $missing_base = $parser->{opt_missing_pragmadir}; | ||||
166 | }elsif( defined($parser->{opt_missing_dir}) ) | ||||||
167 | { | ||||||
168 | 2 | 5 | $missing_base = $parser->{opt_missing_dir}; | ||||
169 | }else | ||||||
170 | { | ||||||
171 | 2 | 6 | $missing_base = $parser->{out_topdir}; | ||||
172 | } | ||||||
173 | 4 | 20 | my $href = $missing_base . $parser->escapeUrl($file1); | ||||
174 | 4 | 46 | $link_info = { | ||||
175 | base => $missing_base, | ||||||
176 | path => $file1, | ||||||
177 | href => $href, | ||||||
178 | }; | ||||||
179 | 4 | 65 | $parser->{linkcache}{$target} = $link_info, | ||||
180 | $parser->verbmsg(VERBOSE_NOLINK,"[$target] not found ==> $href\n"); | ||||||
181 | } | ||||||
182 | } | ||||||
183 | |||||||
184 | 4 | 50 | 14 | if( !defined($link_info->{href}) ) | |||
185 | { | ||||||
186 | 0 | 0 | my $base = $link_info->{base}; | ||||
187 | 0 | 0 | my $path = $link_info->{path}; | ||||
188 | 0 | 0 | $link_info->{href} = $base . $parser->escapeUrl($path); | ||||
189 | } | ||||||
190 | |||||||
191 | 4 | 8 | my $link_to = $link_info->{href}; | ||||
192 | 4 | 100 | 13 | if( $sec_anchor ) | |||
193 | { | ||||||
194 | 1 | 169 | $link_to .= '#' . $parser->makelinkanchor($sec_anchor); | ||||
195 | } | ||||||
196 | |||||||
197 | 4 | 50 | 33 | 16 | if( !defined($text)||$text eq '' ) | ||
198 | { | ||||||
199 | 4 | 64 | $text = $parser->makelinktext(@_[1..$#_]); | ||||
200 | } | ||||||
201 | #print STDERR "($lang,$text,$target,$sec) ==> [$link_to]\n"; | ||||||
202 | 4 | 201 | $text = $parser->escapeHtml($text); | ||||
203 | 4 | 11 | $link_to = $parser->escapeHtml($link_to); | ||||
204 | 4 | 19 | qq($text); | ||||
205 | } | ||||||
206 | |||||||
207 | # ----------------------------------------------------------------------------- | ||||||
208 | # $parser->_map_head_word($ptree) | ||||||
209 | # head のテキストに基本訳を付ける | ||||||
210 | # | ||||||
211 | sub _map_head_word | ||||||
212 | { | ||||||
213 | 87 | 87 | 306 | my ($parser,$ptree) = @_; | |||
214 | 87 | 100 | 1854 | ref($ptree) or $ptree = Pod::Paragraph->new(-text=>$ptree); | |||
215 | |||||||
216 | 87 | 772 | my $text = $ptree->text(); | ||||
217 | 87 | 326 | $text =~ s/^\s+//; | ||||
218 | 87 | 449 | $text =~ s/\s+$//; | ||||
219 | |||||||
220 | 87 | 1163 | my @text = Pod::MultiLang::Dict->find_word($parser->{langs},$text); | ||||
221 | 87 | 172 | my $num_found = grep{defined($_)}@text; | ||||
98 | 277 | ||||||
222 | 87 | 100 | 555 | if( $num_found==0 ) | |||
223 | { | ||||||
224 | 76 | 717 | return $ptree; | ||||
225 | } | ||||||
226 | 11 | 50 | 118 | if( $num_found==1 ) | |||
227 | { | ||||||
228 | 11 | 13 | my $i = 0; | ||||
229 | 11 | 23 | foreach(@text) | ||||
230 | { | ||||||
231 | 22 | 50 | 66 | 169 | if( defined($_) && $parser->{langs}[$i] && $parser->{langs}[$i]eq'en' ) | ||
66 | |||||||
232 | { | ||||||
233 | # default only. | ||||||
234 | 0 | 0 | return $ptree; | ||||
235 | } | ||||||
236 | 22 | 55 | ++$i; | ||||
237 | } | ||||||
238 | } | ||||||
239 | 11 | 21 | my $i=0; | ||||
240 | 11 | 17 | my $result = $text; | ||||
241 | 11 | 21 | foreach(@text) | ||||
242 | { | ||||||
243 | 22 | 100 | 49 | if( defined($_) ) | |||
244 | { | ||||||
245 | 11 | 37 | $result .= "\nJ<$parser->{langs}[$i];$_>"; | ||||
246 | } | ||||||
247 | 22 | 38 | ++$i; | ||||
248 | } | ||||||
249 | 11 | 57 | $ptree->text($result); | ||||
250 | 11 | 63 | $ptree; | ||||
251 | } | ||||||
252 | |||||||
253 | # ----------------------------------------------------------------------------- | ||||||
254 | # new | ||||||
255 | # コンストラクタ | ||||||
256 | # poddir => [] | ||||||
257 | # Pkg/Class.html | ||||||
258 | # Pkg/Pkg-Class.html | ||||||
259 | # Pkg/Pkg-Class-[\d\.]+.html | ||||||
260 | # Pkg-Class.html | ||||||
261 | # Pkg-Class-[\d\.]+.html | ||||||
262 | # あたりかなぁ。。? | ||||||
263 | # | ||||||
264 | sub new | ||||||
265 | { | ||||||
266 | 43 | 43 | 1 | 77616 | my $pkg = shift; | ||
267 | 43 | 50 | 2560 | ref($pkg) and $pkg = ref($pkg); | |||
268 | 43 | 100 | 66 | 776 | my %arg = @_&&ref($_[0])eq'HASH'?%{$_[0]}:@_; | ||
38 | 320 | ||||||
269 | |||||||
270 | # SUPER クラスを使ってインスタンスを生成. | ||||||
271 | # | ||||||
272 | 43 | 100 | 112 | my @passarg = map{exists($arg{$_})?($_=>$arg{$_}):()}qw(langs); | |||
43 | 216 | ||||||
273 | 43 | 430 | my $parser = $pkg->SUPER::new(@passarg); | ||||
274 | |||||||
275 | # 見出し変換辞書のロード | ||||||
276 | # | ||||||
277 | 43 | 100 | 234 | exists($arg{langs}) and Pod::MultiLang::Dict->load_dict($arg{langs}); | |||
278 | |||||||
279 | # 設定を記録 | ||||||
280 | # | ||||||
281 | 43 | 50 | 627 | $parser->{opt_poddir} = $arg{poddir}||[]; | |||
282 | 43 | 194 | $parser->{opt_css} = $arg{css}; | ||||
283 | 43 | 114 | $parser->{opt_made} = $arg{made}; | ||||
284 | 43 | 108 | $parser->{opt_missing_poddir} = $arg{missing_poddir}; | ||||
285 | 43 | 94 | $parser->{opt_missing_pragmadir} = $arg{missing_pragmadir}; | ||||
286 | 43 | 104 | $parser->{opt_missing_dir} = $arg{missing_dir}; | ||||
287 | 43 | 140 | $parser->{opt_use_index} = 1; | ||||
288 | 43 | 50 | 426 | $parser->{opt_default_lang} = $arg{default_lang} || DEFAULT_LANG; | |||
289 | 43 | 100 | 291 | $parser->{_in_charset} = $arg{in_charset} || 'utf-8'; | |||
290 | 43 | 100 | 1367 | $parser->{_out_charset} = $arg{out_charset} || 'utf-8'; | |||
291 | 43 | 104 | $parser->{_langstack} = undef; | ||||
292 | 43 | 142 | $parser->{linkcache} = {}; | ||||
293 | |||||||
294 | 43 | 776 | @$parser{qw(_verbose _verbout | ||||
295 | langs _expandlangs _default_lang _fetchlangs | ||||||
296 | _linkwords _linkwords_keys | ||||||
297 | _langstack _neststack _skipblock _iseqstack | ||||||
298 | paras heads items | ||||||
299 | _cssprefix | ||||||
300 | out_outfile out_outdir out_topdir out_css out_made | ||||||
301 | _outhtml_heading_toc | ||||||
302 | _outhtml_heading_index | ||||||
303 | _outhtml_plain_title | ||||||
304 | _outhtml_block_title | ||||||
305 | )} = (); | ||||||
306 | 43 | 302 | @$parser{qw( _INFILE _OUTFILE _PARSEOPTS _CUTTING | ||||
307 | _INPUT _OUTPUT _CALLBACKS _TOP_STREAM _ERRORSUB | ||||||
308 | _INPUT_STREAMS | ||||||
309 | )} = (); | ||||||
310 | #_SELECTED_SECTIONS | ||||||
311 | #lock_keys(%$parser); | ||||||
312 | |||||||
313 | # ディレクトリは末尾/付きに正規化 | ||||||
314 | 43 | 81 | foreach(@{$parser->{opt_poddir}},@$parser{qw(opt_missing_poddir opt_missing_pragmadir opt_missing_dir)}) | ||||
43 | 150 | ||||||
315 | { | ||||||
316 | 129 | 100 | 100 | 416 | defined($_) && !m/\/$/ and $_.='/'; | ||
317 | } | ||||||
318 | 43 | 354 | $parser; | ||||
319 | } | ||||||
320 | |||||||
321 | # ----------------------------------------------------------------------------- | ||||||
322 | # begin_pod | ||||||
323 | # 初期化 | ||||||
324 | # | ||||||
325 | sub begin_pod | ||||||
326 | { | ||||||
327 | 43 | 43 | 1 | 8746 | my ($parser) = @_; | ||
328 | 43 | 147 | &Pod::MultiLang::begin_pod; | ||||
329 | |||||||
330 | 43 | 118 | $parser->{_verbose} = $VERBOSE_DEFAULT; | ||||
331 | 43 | 86 | $parser->{_verbout} = \*STDERR; | ||||
332 | 43 | 78 | $parser->{_expandlangs} = undef; | ||||
333 | 43 | 118 | $parser->{_default_lang} = $parser->{opt_default_lang}; | ||||
334 | 43 | 74 | $parser->{_fetchlangs} = undef; | ||||
335 | 43 | 87 | $parser->{_linkwords} = undef; | ||||
336 | 43 | 59 | $parser->{_linkwords_keys} = undef; | ||||
337 | 43 | 103 | $parser->{_langstack} = [undef]; | ||||
338 | 43 | 135 | $parser->{_cssprefix} = 'pod_'; | ||||
339 | |||||||
340 | 43 | 424 | my $outfile = $parser->output_file(); | ||||
341 | 43 | 50 | 400 | file_name_is_absolute($outfile) or $outfile = File::Spec->rel2abs($outfile); | |||
342 | 43 | 4781 | my $outdir = (File::Spec->splitpath($outfile))[1]; | ||||
343 | 43 | 113 | my $css = $parser->{opt_css}; | ||||
344 | 43 | 50 | 33 | 175 | if( $css && !file_name_is_absolute($css) ) | ||
345 | { | ||||||
346 | 0 | 0 | $css = File::Spec->abs2rel(File::Spec->rel2abs($css),$outdir); | ||||
347 | } | ||||||
348 | 43 | 95 | my $made = $parser->{opt_made}; | ||||
349 | 43 | 240 | $parser->{out_outfile} = $outfile; | ||||
350 | 43 | 84 | $parser->{out_outdir} = $outdir; | ||||
351 | 43 | 50 | 423599 | $parser->{out_topdir} = File::Spec->abs2rel(cwd(),$outdir)||'.'; | |||
352 | 43 | 596 | $parser->{out_css} = $css; | ||||
353 | 43 | 155 | $parser->{out_made} = $made; | ||||
354 | |||||||
355 | # ディレクトリは末尾/付きに正規化 | ||||||
356 | 43 | 209 | foreach(@$parser{qw(out_topdir out_outdir)}) | ||||
357 | { | ||||||
358 | 86 | 100 | 66 | 2692 | defined($_) && !m/\/$/ and $_.='/'; | ||
359 | } | ||||||
360 | |||||||
361 | 43 | 50 | 6110 | if( $parser->{_verbose}>=VERBOSE_FULL ) | |||
362 | { | ||||||
363 | 0 | 0 | my $out = $$parser{_verbout}; | ||||
364 | 0 | 0 | print $out $parser->input_file()."\n"; | ||||
365 | 0 | 0 | print $out "scan...\n"; | ||||
366 | } | ||||||
367 | } | ||||||
368 | |||||||
369 | # ----------------------------------------------------------------------------- | ||||||
370 | # interior_sequence | ||||||
371 | # 装飾符号の展開 | ||||||
372 | # | ||||||
373 | sub interior_sequence | ||||||
374 | { | ||||||
375 | 12 | 12 | 1 | 26 | my ($parser, $seq_command, $seq_argument) = @_; | ||
376 | ## Expand an interior sequence; sample actions might be: | ||||||
377 | 12 | 50 | 104 | if( $seq_command eq 'I' ) | |||
50 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
0 | |||||||
0 | |||||||
0 | |||||||
0 | |||||||
0 | |||||||
378 | { | ||||||
379 | 0 | 0 | return qq($seq_argument); | ||||
380 | }elsif( $seq_command eq 'B' ) | ||||||
381 | { | ||||||
382 | 0 | 0 | return qq($seq_argument); | ||||
383 | }elsif( $seq_command eq 'C' ) | ||||||
384 | { | ||||||
385 | 0 | 0 | return qq($seq_argument ); |
||||
386 | }elsif( $seq_command eq 'L' ) | ||||||
387 | { | ||||||
388 | 0 | 0 | $parser->resolveLink($seq_argument); | ||||
389 | }elsif( $seq_command eq 'E' ) | ||||||
390 | { | ||||||
391 | 12 | 77 | return $parser->resolvePodEscape($seq_argument); | ||||
392 | }elsif( $seq_command eq 'F' ) | ||||||
393 | { | ||||||
394 | 0 | 0 | return qq($seq_argument); | ||||
395 | }elsif( $seq_command eq 'S' ) | ||||||
396 | { | ||||||
397 | 0 | 0 | return qq( |
||||
398 | }elsif( $seq_command eq 'X' ) | ||||||
399 | { | ||||||
400 | 0 | 0 | return ''; | ||||
401 | }elsif( $seq_command eq 'Z' ) | ||||||
402 | { | ||||||
403 | 0 | 0 | return ''; | ||||
404 | }elsif( $seq_command eq 'J' ) | ||||||
405 | { | ||||||
406 | 0 | 0 | my ($lang,$text) = $parser->parseLang($seq_argument); | ||||
407 | 0 | 0 | 0 | if( $parser->{_expandlangs} ) | |||
408 | { | ||||||
409 | 0 | 0 | 0 | if( !grep{$lang eq $_}@{$parser->{_expandlangs}} ) | |||
0 | 0 | ||||||
0 | 0 | ||||||
410 | { | ||||||
411 | 0 | 0 | return ''; | ||||
412 | } | ||||||
413 | 0 | 0 | 0 | grep{$lang eq $_}@{$parser->{_fetchlangs}} or push(@{$parser->{_fetchlangs}},$lang); | |||
0 | 0 | ||||||
0 | 0 | ||||||
0 | 0 | ||||||
414 | } | ||||||
415 | 0 | 0 | return qq($text); | ||||
416 | } | ||||||
417 | } | ||||||
418 | |||||||
419 | # ----------------------------------------------------------------------------- | ||||||
420 | # plainize | ||||||
421 | # ptreeを単純テキストに. | ||||||
422 | # | ||||||
423 | sub plainize | ||||||
424 | { | ||||||
425 | 4 | 4 | 1 | 7 | my ($parser,$ptree) = @_; | ||
426 | 4 | 100 | 45 | if( $ptree->isa('Pod::InteriorSequence') ) | |||
427 | { | ||||||
428 | 2 | 10 | $ptree = $ptree->parse_tree(); | ||||
429 | } | ||||||
430 | 4 | 100 | 38 | if( $ptree->isa('Pod::ParseTree') ) | |||
431 | { | ||||||
432 | 3 | 6 | my $text = ''; | ||||
433 | 3 | 16 | foreach($ptree->children()) | ||||
434 | { | ||||||
435 | 3 | 50 | 11 | $text .= ref($_) ? $parser->plainize($_) : $_; | |||
436 | } | ||||||
437 | 3 | 22 | return $text; | ||||
438 | } | ||||||
439 | 1 | 50 | 6 | if( $ptree->isa('Pod::Paragraph') ) | |||
440 | { | ||||||
441 | 1 | 5 | my $text = $ptree->text(); | ||||
442 | 1 | 23 | $text =~ s/^(.+?)(J<)/J<< $parser->{_default_lang}; $1 >>$2/s; | ||||
443 | 1 | 295 | return $parser->parse_text( { -expand_seq => \&_plainize_iseq, | ||||
444 | -expand_ptree => \&plainize, | ||||||
445 | }, | ||||||
446 | $text, | ||||||
447 | ($ptree->file_line())[1], | ||||||
448 | ); | ||||||
449 | } | ||||||
450 | 0 | 0 | die "unknown type [$ptree]"; | ||||
451 | } | ||||||
452 | |||||||
453 | # ----------------------------------------------------------------------------- | ||||||
454 | # _plainize_iseq | ||||||
455 | # 装飾符号を単純テキストに. | ||||||
456 | # | ||||||
457 | sub _plainize_iseq | ||||||
458 | { | ||||||
459 | 2 | 2 | 5 | my ($parser, $iseq) = @_; | |||
460 | 2 | 16 | my $cmd = $iseq->cmd_name(); | ||||
461 | 2 | 50 | 33 | 69 | if( $cmd eq 'I' || $cmd eq 'B' || $cmd eq 'C' || $cmd eq 'F' || $cmd eq 'S' ) | ||
50 | 33 | ||||||
50 | 33 | ||||||
50 | 33 | ||||||
50 | 33 | ||||||
462 | { | ||||||
463 | 0 | 0 | return $parser->plainize($iseq); | ||||
464 | }elsif( $cmd eq 'X' || $cmd eq 'Z' ) | ||||||
465 | { | ||||||
466 | 0 | 0 | return ''; | ||||
467 | }elsif( $cmd eq 'E' ) | ||||||
468 | { | ||||||
469 | 0 | 0 | return $parser->resolvePodEscape($parser->plainize($iseq->parse_tree())); | ||||
470 | }elsif( $cmd eq 'L' ) | ||||||
471 | { | ||||||
472 | 0 | 0 | return '_'; | ||||
473 | }elsif( $cmd eq 'J' ) | ||||||
474 | { | ||||||
475 | 2 | 12 | my $text = $parser->plainize($iseq); | ||||
476 | 2 | 14 | (my $lang,$text) = $parser->parseLang($text); | ||||
477 | 2 | 50 | 4 | if( grep{$_ eq 'en'}@{$parser->{langs}} ) | |||
4 | 0 | 22 | |||||
2 | 5 | ||||||
478 | { | ||||||
479 | # if langs contains en, use en. | ||||||
480 | 2 | 100 | 268 | return $lang eq 'en' ? $text : ''; | |||
481 | }elsif( $lang eq $parser->{langs}[0] ) | ||||||
482 | { | ||||||
483 | # no en, use first lang. | ||||||
484 | 0 | 0 | return $text; | ||||
485 | }else | ||||||
486 | { | ||||||
487 | 0 | 0 | return ''; | ||||
488 | } | ||||||
489 | } | ||||||
490 | 0 | 0 | ''; | ||||
491 | } | ||||||
492 | |||||||
493 | # ----------------------------------------------------------------------------- | ||||||
494 | # buildhtml | ||||||
495 | # paraobj からhtmlを生成 | ||||||
496 | # | ||||||
497 | sub buildhtml | ||||||
498 | { | ||||||
499 | 130 | 130 | 1 | 214 | my ($parser,$paraobj) = @_; | ||
500 | |||||||
501 | 130 | 181 | my $ptree; | ||||
502 | 130 | 50 | 665 | if( isa($paraobj,'Pod::Paragraph') ) | |||
503 | { | ||||||
504 | 130 | 22854 | $ptree = $parser->parse_text($paraobj->text(),($paraobj->file_line())[1]); | ||||
505 | }else | ||||||
506 | { | ||||||
507 | 0 | 0 | $ptree = $paraobj; | ||||
508 | } | ||||||
509 | |||||||
510 | # [langs..,,no-lang]; | ||||||
511 | 130 | 858 | my @list = $parser->_buildhtml_parse($ptree); | ||||
512 | 130 | 193 | my @html; | ||||
513 | 130 | 208 | for( my $i=0; $i<=$#{$parser->{langs}}; ++$i ) | ||||
276 | 1006 | ||||||
514 | { | ||||||
515 | 146 | 100 | 667 | if( defined($list[$i]) ) | |||
100 | |||||||
516 | { | ||||||
517 | 12 | 38 | my $cls = "$parser->{_cssprefix}lang_$parser->{langs}[$i]"; | ||||
518 | 12 | 85 | my $text = $list[$i]; | ||||
519 | 12 | 45 | push(@html,qq($list[$i])); | ||||
520 | }elsif( $parser->{langs}[$i]eq$parser->{_default_lang} ) | ||||||
521 | { | ||||||
522 | 130 | 100 | 207 | if( grep{defined}@list[0..$#{$parser->{langs}}] ) | |||
146 | 482 | ||||||
130 | 332 | ||||||
523 | { | ||||||
524 | 12 | 37 | my $cls = "$parser->{_cssprefix}lang_$parser->{langs}[$i]"; | ||||
525 | 12 | 48 | push(@html,qq($list[-1])); | ||||
526 | }else | ||||||
527 | { | ||||||
528 | 118 | 455 | my $cls = "$parser->{_cssprefix}lang"; | ||||
529 | 118 | 472 | push(@html,qq($list[-1])); | ||||
530 | } | ||||||
531 | } | ||||||
532 | } | ||||||
533 | |||||||
534 | 130 | 356 | my $ret = join("\n",@html); | ||||
535 | 130 | 50 | 338 | if( $ret eq '' ) | |||
536 | { | ||||||
537 | 0 | 0 | 0 | 0 | if( defined($list[-1]) && $list[-1] ne '' ) | ||
538 | { | ||||||
539 | 0 | 0 | $ret = $list[-1]; | ||||
540 | }else | ||||||
541 | { | ||||||
542 | 0 | 0 | foreach (@list,'{empty}') | ||||
543 | { | ||||||
544 | 0 | 0 | 0 | defined($_) and $ret = $_,last; | |||
545 | } | ||||||
546 | } | ||||||
547 | } | ||||||
548 | 130 | 2898 | $ret; | ||||
549 | } | ||||||
550 | 0 | 0 | 0 | 0 | sub _a2s{ join('-',map{defined($_)?"[$_]":'{undef}'}@_) } | ||
0 | 0 | ||||||
551 | |||||||
552 | sub _find_lang_index | ||||||
553 | { | ||||||
554 | 158 | 158 | 467 | my ($this,$lang) = @_; | |||
555 | 158 | 289 | for( my $i=0; $i<=$#{$this->{langs}}; ++$i ) | ||||
190 | 745 | ||||||
556 | { | ||||||
557 | 190 | 100 | 623 | if( $this->{langs}[$i] eq $lang ) | |||
558 | { | ||||||
559 | 158 | 1240 | return $i; | ||||
560 | } | ||||||
561 | } | ||||||
562 | 0 | 0 | undef; | ||||
563 | } | ||||||
564 | # ----------------------------------------------------------------------------- | ||||||
565 | # _buildhtml_parse | ||||||
566 | # 言語毎に分解. | ||||||
567 | # | ||||||
568 | sub _buildhtml_parse | ||||||
569 | { | ||||||
570 | 158 | 158 | 359 | my ($parser,$ptree,$inlang) = @_; | |||
571 | 158 | 233 | my @ret = ((undef)x@{$parser->{langs}},''); | ||||
158 | 655 | ||||||
572 | 158 | 100 | 530 | my $idx_default_lang = $parser->_find_lang_index($parser->{_default_lang})||0; | |||
573 | |||||||
574 | 158 | 50 | 867 | if( can($ptree,'parse_tree') ) | |||
575 | { | ||||||
576 | 158 | 654 | $ptree = $ptree->parse_tree(); | ||||
577 | } | ||||||
578 | 158 | 0 | 1454 | my @children = can($ptree,'children')?$ptree->children():isa($ptree,'ARRAY')?@$ptree:die "unknown object : $ptree"; | |||
50 | |||||||
579 | #print STDERR "in: @{[scalar@children]} ",_a2s(@children),"\n"; | ||||||
580 | 158 | 356 | foreach (@children) | ||||
581 | { | ||||||
582 | 190 | 100 | 595 | if( !ref($_) ) | |||
583 | { | ||||||
584 | # plain text. | ||||||
585 | 160 | 690 | my $text = $parser->escapeHtml($_); | ||||
586 | 160 | 455 | $ret[-1] .= $text; | ||||
587 | 160 | 461 | next; | ||||
588 | } | ||||||
589 | 30 | 100 | 218 | if( $_->cmd_name() eq 'L' ) | |||
590 | { | ||||||
591 | # link iseq. | ||||||
592 | #print STDERR "link iseq\n"; | ||||||
593 | 4 | 55 | my $link = $_->raw_text(); | ||||
594 | 4 | 40 | $link =~ s/^L\<+\s*//; | ||||
595 | 4 | 40 | $link =~ s/\s*\>+$//; | ||||
596 | 4 | 66 | my ($text, undef, $name, $section, $type) = parselink($link); | ||||
597 | 4 | 50 | 66 | 315 | if( !$section && $name =~ / / ) | ||
598 | { | ||||||
599 | 0 | 0 | $section = $name; | ||||
600 | 0 | 0 | $name = ''; | ||||
601 | } | ||||||
602 | 4 | 50 | 16 | if( $link !~ /J\ ) | |||
603 | { | ||||||
604 | 4 | 5 | my $link; | ||||
605 | 4 | 50 | 19 | if( $type eq 'man' ) | |||
50 | |||||||
606 | { | ||||||
607 | 0 | 0 | $link = $parser->escapeHtml($name); | ||||
608 | }elsif( $type eq 'url' ) | ||||||
609 | { | ||||||
610 | 0 | 0 | my $url = $parser->escapeHtml($name); | ||||
611 | 0 | 0 | my $text = $parser->escapeHtml($name); | ||||
612 | 0 | 0 | $link = qq($text); | ||||
613 | }else | ||||||
614 | { | ||||||
615 | 4 | 33 | 48 | my $lang = $parser->{_langstack}[-1]||$parser->{_default_lang}; | |||
616 | 4 | 19 | $link =$parser->makelink($lang,$text,$name,$section); | ||||
617 | } | ||||||
618 | 4 | 50 | 14 | if( defined($ret[-1]) ) | |||
619 | { | ||||||
620 | 4 | 8 | $ret[-1] .= $link; | ||||
621 | }else | ||||||
622 | { | ||||||
623 | 0 | 0 | $ret[-1] = $link; | ||||
624 | } | ||||||
625 | 4 | 14 | next; | ||||
626 | } | ||||||
627 | 0 | 0 | my $line = ($_->file_line())[1]; | ||||
628 | 0 | 0 | foreach($text, $name, $section) | ||||
629 | { | ||||||
630 | 0 | 0 | 0 | if( !defined($_) ) | |||
631 | { | ||||||
632 | 0 | 0 | $_ = [(undef)x$#ret]; | ||||
633 | 0 | 0 | next; | ||||
634 | } | ||||||
635 | 0 | 0 | my $ptree = $parser->parse_text($_,$line); | ||||
636 | 0 | 0 | my @child = $parser->_buildhtml_parse($ptree); | ||||
637 | # default_lang が未定義だったら, 言語指定なし部分を充てる. | ||||||
638 | # (全部未定義なら必要ない) | ||||||
639 | 0 | 0 | 0 | 0 | if( defined($idx_default_lang) | ||
0 | 0 | 0 | |||||
640 | && !defined($child[$idx_default_lang]) | ||||||
641 | 0 | 0 | && grep{defined($_)}@child[0..$#{$parser->{langs}}] ) | ||||
642 | { | ||||||
643 | 0 | 0 | $child[$idx_default_lang] = $child[-1]; | ||||
644 | } | ||||||
645 | 0 | 0 | foreach(grep{defined($_)}@child) | ||||
0 | 0 | ||||||
646 | { | ||||||
647 | 0 | 0 | s/^\s+//; | ||||
648 | 0 | 0 | s/\s+$//; | ||||
649 | } | ||||||
650 | 0 | 0 | $_ = \@child; | ||||
651 | } | ||||||
652 | # 装飾符号の展開. | ||||||
653 | 0 | 0 | my $cmd_name = $_->cmd_name(); | ||||
654 | 0 | 0 | 0 | my $sec_anchor = $$section[-1]||$$section[$idx_default_lang]||''; | |||
655 | 0 | 0 | 0 | my $lang = $parser->{_langstack}[-1]||$parser->{_default_lang}; | |||
656 | 0 | 0 | my $i = $parser->_find_lang_index($lang); | ||||
657 | 0 | 0 | 0 | defined($i) or $i = $idx_default_lang; | |||
658 | { | ||||||
659 | |||||||
660 | 0 | 0 | 0 | my $text = $$text[$i]||$$text[$idx_default_lang]||''; | |||
0 | 0 | ||||||
661 | 0 | 0 | 0 | my $name = $$name[$i]||$$name[$idx_default_lang]||''; | |||
662 | 0 | 0 | 0 | my $section = $$section[$i]||$$section[$idx_default_lang]||''; | |||
663 | 0 | 0 | 0 | my $lang = $parser->{langs}[$i]||$parser->{_default_lang}; | |||
664 | 0 | 0 | my $link; | ||||
665 | 0 | 0 | 0 | if( $type eq 'man' ) | |||
0 | |||||||
666 | { | ||||||
667 | 0 | 0 | $link = $parser->escapeHtml($name); | ||||
668 | }elsif( $type eq 'url' ) | ||||||
669 | { | ||||||
670 | 0 | 0 | my $url = $parser->escapeHtml($name); | ||||
671 | 0 | 0 | my $text = $parser->escapeHtml($name); | ||||
672 | 0 | 0 | $link = qq($text); | ||||
673 | }else | ||||||
674 | { | ||||||
675 | 0 | 0 | $link =$parser->makelink($lang,$text,$name,$section,$sec_anchor); | ||||
676 | } | ||||||
677 | 0 | 0 | 0 | if( defined($ret[-1]) ) | |||
678 | { | ||||||
679 | 0 | 0 | $ret[-1] .= $link; | ||||
680 | }else | ||||||
681 | { | ||||||
682 | 0 | 0 | $ret[-1] = $link; | ||||
683 | } | ||||||
684 | } | ||||||
685 | 0 | 0 | next; | ||||
686 | } # if cmd_name eq 'L' | ||||||
687 | 26 | 100 | 143 | if( $_->cmd_name() ne 'J' ) | |||
688 | { | ||||||
689 | # normal iseq. | ||||||
690 | #print STDERR "normal iseq\n"; | ||||||
691 | 12 | 234 | my @child = $parser->_buildhtml_parse($_->parse_tree()); | ||||
692 | #print STDERR" child : $#child "._a2s(@child)."\n"; | ||||||
693 | # default_lang が未定義だったら, 言語指定なし部分を充てる. | ||||||
694 | 12 | 32 | for( my $i=0; $i<=$#{$parser->{langs}}; ++$i ) | ||||
12 | 45 | ||||||
695 | { | ||||||
696 | 12 | 50 | 52 | if( $parser->{langs}[$i] eq $parser->{_default_lang} ) | |||
697 | { | ||||||
698 | 12 | 50 | 33 | 91 | !defined($child[$i]) &&grep{defined}@child[0..$#{$parser->{langs}}] and $child[$i] = $child[-1]; | ||
12 | 64 | ||||||
12 | 38 | ||||||
699 | #print STDERR " fallback [$child[-1]] ==> [$parser->{_default_lang}#$i]\n"; | ||||||
700 | 12 | 34 | last; | ||||
701 | } | ||||||
702 | } | ||||||
703 | # 装飾符号の展開. | ||||||
704 | 12 | 65 | my $cmd_name = $_->cmd_name(); | ||||
705 | 12 | 52 | for( my $i=0; $i<=$#child; ++$i ) | ||||
706 | { | ||||||
707 | 24 | 100 | 127 | if( !defined($child[$i]) ) | |||
708 | { | ||||||
709 | 12 | 31 | next; | ||||
710 | } | ||||||
711 | 12 | 160 | $child[$i] = $parser->interior_sequence($cmd_name,$child[$i]); | ||||
712 | 12 | 50 | 39 | if( defined($ret[$i]) ) | |||
713 | { | ||||||
714 | 12 | 46 | $ret[$i] .= $child[$i]; | ||||
715 | }else | ||||||
716 | { | ||||||
717 | 0 | 0 | $ret[$i] = $child[$i]; | ||||
718 | } | ||||||
719 | } | ||||||
720 | 12 | 67 | next; | ||||
721 | } # if cmd_name ne 'J' | ||||||
722 | |||||||
723 | # lang iseq. | ||||||
724 | 14 | 150 | my $iseq = $_; | ||||
725 | 14 | 50 | 104 | my $first = ($iseq->parse_tree()->children())[0] || ''; | |||
726 | 14 | 50 | 32 | push(@{$parser->{_langstack}},$first=~/^\s*(\w+)\s*[\/;]/?$1:$parser->{_langstack}[-1]); | |||
14 | 107 | ||||||
727 | 14 | 150 | my @child = $parser->_buildhtml_parse($iseq->parse_tree()); | ||||
728 | 14 | 23 | pop(@{$parser->{_langstack}}); | ||||
14 | 29 | ||||||
729 | 14 | 69 | $child[-1] =~ s,^\s*(\w+)\s*[/;]\s*,,; | ||||
730 | 14 | 36 | my $lang = $1; | ||||
731 | 14 | 50 | 34 | if( !defined($lang) ) | |||
732 | { | ||||||
733 | 0 | 0 | $parser->verbmsg(VERBOSE_ERROR,"no lang in J<>, use default-lang [$parser->{_default_lang}] at ".$iseq->file_line()."\n"); | ||||
734 | 0 | 0 | $lang = $parser->{_default_lang}; | ||||
735 | } | ||||||
736 | 14 | 42 | for( my $i=0; $i<=$#{$parser->{langs}}; ++$i ) | ||||
14 | 45 | ||||||
737 | { | ||||||
738 | 14 | 50 | 40 | $parser->{langs}[$i] ne $lang and next; | |||
739 | 14 | 29 | $ret[$i] .= $child[-1]; | ||||
740 | 14 | 51 | last; | ||||
741 | } | ||||||
742 | #print STDERR " iseq: $#ret ",_a2s(@ret),"\n"; | ||||||
743 | } | ||||||
744 | 158 | 50 | 867 | $ret[-1]=~/\S/ or $ret[-1]=''; | |||
745 | #print "out: @{[scalar@ret]} ",_a2s(@ret),"\n"; | ||||||
746 | 158 | 962 | @ret; | ||||
747 | } | ||||||
748 | |||||||
749 | # ----------------------------------------------------------------------------- | ||||||
750 | # _parse_iseq_J | ||||||
751 | # ($lang,$text) = $parser->_parse_iseq_J($iseq); | ||||||
752 | # | ||||||
753 | sub _parse_iseq_J | ||||||
754 | { | ||||||
755 | 0 | 0 | 0 | my ($parser,$iseq) = @_; | |||
756 | 0 | 0 | my @children = $iseq->parse_tree->children(); | ||||
757 | 0 | 0 | for( my $i=0; $i<@children; ++$i ) | ||||
758 | { | ||||||
759 | 0 | 0 | 0 | ref($children[$i]) and next; | |||
760 | 0 | 0 | 0 | my ($lang_last,$text_head) = split('/',$_,2) | |||
761 | or next; | ||||||
762 | |||||||
763 | 0 | 0 | my $lang = [@children[0..$i-1],$lang_last]; | ||||
764 | 0 | 0 | my $text = [$text_head,@children[$i+1..$#children]]; | ||||
765 | 0 | 0 | my ($file,$line) = $iseq->file_line(); | ||||
766 | 0 | 0 | my $text_line = $line + $parser->_countnewline(@$lang); | ||||
767 | 0 | 0 | my $lang_iseq = Pod::InteriorSequence->new( -name => '', | ||||
768 | -file => $file, | ||||||
769 | -line => $line, | ||||||
770 | -ldelim => '', | ||||||
771 | -rdelim => '', | ||||||
772 | -ptree => Pod::ParseTree->new($lang), | ||||||
773 | ); | ||||||
774 | 0 | 0 | my $text_iseq = Pod::InteriorSequence->new( -name => '', | ||||
775 | -file => $file, | ||||||
776 | -line => $text_line, | ||||||
777 | -ldelim => '', | ||||||
778 | -rdelim => '', | ||||||
779 | -ptree => Pod::ParseTree->new($text), | ||||||
780 | ); | ||||||
781 | 0 | 0 | return ($lang_iseq,$text_iseq); | ||||
782 | } | ||||||
783 | 0 | 0 | (undef,$iseq); | ||||
784 | } | ||||||
785 | |||||||
786 | # ----------------------------------------------------------------------------- | ||||||
787 | # _countnewline | ||||||
788 | # | ||||||
789 | sub _countnewline | ||||||
790 | { | ||||||
791 | 0 | 0 | 0 | my $line=0; | |||
792 | 0 | 0 | foreach my $t (@_[1..$#_]) | ||||
793 | { | ||||||
794 | 0 | 0 | $line += $t =~ tr/\n/\n/; | ||||
795 | } | ||||||
796 | 0 | 0 | $line; | ||||
797 | } | ||||||
798 | |||||||
799 | # ----------------------------------------------------------------------------- | ||||||
800 | # buildtitle | ||||||
801 | # タイトルを作成. ヘッダ用と本文用. | ||||||
802 | # | ||||||
803 | sub buildtitle | ||||||
804 | { | ||||||
805 | 1 | 1 | 1 | 2 | my ($parser,$paraobj) = @_; | ||
806 | |||||||
807 | # [langs..,,no-lang]; | ||||||
808 | 1 | 108 | my @list = $parser->_buildhtml_parse($parser->parse_text($paraobj->text())); | ||||
809 | 1 | 22 | my $plain_title; | ||||
810 | 1 | 2 | for( my $i=0; $i<=$#{$parser->{langs}}; ++$i ) | ||||
1 | 4 | ||||||
811 | { | ||||||
812 | 1 | 50 | 4 | if( defined($list[$i]) ) | |||
0 | |||||||
813 | { | ||||||
814 | 1 | 1 | $plain_title = $list[$i]; | ||||
815 | 1 | 2 | last; | ||||
816 | }elsif( $parser->{langs}[$i]eq$parser->{_default_lang} ) | ||||||
817 | { | ||||||
818 | 0 | 0 | $plain_title = $list[-1]; | ||||
819 | 0 | 0 | last; | ||||
820 | } | ||||||
821 | } | ||||||
822 | 1 | 50 | 4 | if( !defined($plain_title) ) | |||
823 | { | ||||||
824 | 0 | 0 | 0 | $plain_title = defined($list[-1]) ? $list[-1] : 'untitled'; | |||
825 | } | ||||||
826 | 1 | 3 | $plain_title =~ s/<.*?>//g; | ||||
827 | 1 | 6 | $plain_title =~ s/^\s+//; | ||||
828 | 1 | 4 | $plain_title =~ s/\s+$//; | ||||
829 | |||||||
830 | 1 | 8 | for( my $i=0; $i<=$#{$parser->{langs}}; ++$i ) | ||||
2 | 7 | ||||||
831 | { | ||||||
832 | 2 | 100 | 8 | if( $parser->{langs}[$i]eq$parser->{_default_lang} ) | |||
50 | |||||||
833 | { | ||||||
834 | 1 | 50 | 3 | if( !defined($list[$i]) ) | |||
835 | { | ||||||
836 | 1 | 50 | 3 | if( grep{defined}@list[0..$#{$parser->{langs}}] ) | |||
2 | 7 | ||||||
1 | 8 | ||||||
837 | { | ||||||
838 | 1 | 4 | my $cls = "$parser->{_cssprefix}lang_$parser->{langs}[$i]"; | ||||
839 | 1 | 4 | $list[$i] = qq($list[-1]); | ||||
840 | }else | ||||||
841 | { | ||||||
842 | 0 | 0 | $list[$i] = $list[-1]; | ||||
843 | } | ||||||
844 | }else | ||||||
845 | { | ||||||
846 | 0 | 0 | my $cls = "$parser->{_cssprefix}lang_$parser->{langs}[$i]"; | ||||
847 | 0 | 0 | $list[$i] = qq($list[$i]); | ||||
848 | } | ||||||
849 | 1 | 3 | last; | ||||
850 | }elsif( defined($list[$i]) ) | ||||||
851 | { | ||||||
852 | 1 | 5 | my $cls = "$parser->{_cssprefix}lang_$parser->{langs}[$i]"; | ||||
853 | 1 | 5 | $list[$i] = qq($list[$i]); | ||||
854 | } | ||||||
855 | } | ||||||
856 | 1 | 2 | my $html = join(" \n",grep{defined}@list[0..$#{$parser->{langs}}]); |
||||
2 | 5 | ||||||
1 | 3 | ||||||
857 | 1 | 50 | 5 | if( $html eq '' ) | |||
858 | { | ||||||
859 | 0 | 0 | 0 | my $txt = defined($list[-1]) ? $list[-1] : 'untitled'; | |||
860 | 0 | 0 | my $cls = "$parser->{_cssprefix}lang_default"; | ||||
861 | 0 | 0 | $html = qq($txt); | ||||
862 | } | ||||||
863 | 1 | 2 | my $cls = "$parser->{_cssprefix}title_block"; | ||||
864 | 1 | 4 | my $block_title = qq( \n$html\n \n\n); |
||||
865 | 1 | 8 | ($plain_title,$block_title); | ||||
866 | } | ||||||
867 | |||||||
868 | # ----------------------------------------------------------------------------- | ||||||
869 | # $parser->makelinkanchor($text) | ||||||
870 | # $parser->makelinkanchor($paraobj) | ||||||
871 | # アンカーキーの生成. のxxxの部分. | ||||||
872 | # | ||||||
873 | sub makelinkanchor | ||||||
874 | { | ||||||
875 | 2 | 2 | 1 | 15 | my ($parser,$paraobj) = @_; | ||
876 | 2 | 100 | 26 | my $id = ref($paraobj) ? $parser->plainize($paraobj) : $paraobj; | |||
877 | 2 | 18 | $id =~ s/^\s+//; | ||||
878 | 2 | 10 | $id =~ s/\s+$//; | ||||
879 | 2 | 5 | $id =~ s/\s+/_/g; | ||||
880 | 2 | 12 | $id =~ s/([^\a-zA-Z0-9\-\_\.])/join('',map{sprintf('X%02x',$_)}unpack("C*",$1))/ge; | ||||
0 | 0 | ||||||
0 | 0 | ||||||
881 | 2 | 50 | 29 | $id=~/^[a-zA-Z]/ or $id = 'X'.$id; | |||
882 | 2 | 9 | $id; | ||||
883 | } | ||||||
884 | |||||||
885 | # ----------------------------------------------------------------------------- | ||||||
886 | # addindex | ||||||
887 | # adding to index. | ||||||
888 | # | ||||||
889 | sub addindex | ||||||
890 | { | ||||||
891 | 1 | 1 | 1 | 7 | my ($parser,$hash,$ids,$id,$paraobj) = @_; | ||
892 | |||||||
893 | # make id unique. | ||||||
894 | # | ||||||
895 | 1 | 50 | 6 | if( grep{$_ eq $id} @$ids ) | |||
0 | 0 | ||||||
896 | { | ||||||
897 | 0 | 0 | for(my$i=0;;++$i) | ||||
898 | { | ||||||
899 | 0 | 0 | my $add = sprintf('_%02d',$i); | ||||
900 | 0 | 0 | my $newkey = $id.$add; | ||||
901 | 0 | 0 | 0 | !grep{$_ eq $newkey}@$ids and $id=$newkey,last; | |||
0 | 0 | ||||||
902 | } | ||||||
903 | } | ||||||
904 | 1 | 3 | push(@$ids,$id); | ||||
905 | |||||||
906 | # [langs..,,no-lang]; | ||||||
907 | # | ||||||
908 | 1 | 114 | my @list = $parser->_buildhtml_parse($parser->parse_text($paraobj->text())); | ||||
909 | 1 | 26 | my $i; | ||||
910 | 1 | 3 | foreach(@list) | ||||
911 | { | ||||||
912 | 3 | 100 | 9 | defined($_) or next; | |||
913 | 2 | 8 | s/<.*?>//g; | ||||
914 | 2 | 5 | s/\s+/ /g; | ||||
915 | 2 | 4 | s/^ //; | ||||
916 | 2 | 6 | s/ $//; | ||||
917 | 2 | 50 | 5 | if( $_ eq '' ) | |||
918 | { | ||||||
919 | #my $src = $paraobj->text(); | ||||||
920 | #my $lang = $i<$#list ? $parser->{langs}[$i] : 'default'; | ||||||
921 | #defined($src) or $src = "{undef}"; | ||||||
922 | #defined($lang) or $lang = "{undef}"; | ||||||
923 | #$parser->verbmsg(VERBOSE_WARN,"src:[$src] lang:[$lang] is empty.\n"); | ||||||
924 | 0 | 0 | next; | ||||
925 | } | ||||||
926 | 2 | 8 | $hash->{$_} = $id; | ||||
927 | 2 | 4 | ++$i; | ||||
928 | } | ||||||
929 | 1 | 4 | return $id; | ||||
930 | } | ||||||
931 | |||||||
932 | # ----------------------------------------------------------------------------- | ||||||
933 | # end_pod | ||||||
934 | # at end of parsing pod. | ||||||
935 | # build html and output it. | ||||||
936 | # | ||||||
937 | sub end_pod | ||||||
938 | { | ||||||
939 | 43 | 43 | 1 | 95 | my $parser = shift; | ||
940 | 43 | 104 | my ($command, $paragraph, $line_num) = @_; | ||||
941 | 43 | 552 | $parser->SUPER::end_pod(@_); | ||||
942 | |||||||
943 | 43 | 50 | 148 | if( !@{$parser->{paras}} ) | |||
43 | 292 | ||||||
944 | { | ||||||
945 | 0 | 0 | warn "input has no paragraphs"; | ||||
946 | } | ||||||
947 | |||||||
948 | 43 | 517 | $parser->rebuild(); | ||||
949 | 43 | 200 | $parser->output_html(); | ||||
950 | } | ||||||
951 | |||||||
952 | # ----------------------------------------------------------------------------- | ||||||
953 | # rebuild | ||||||
954 | # build infomations needed for html. | ||||||
955 | # | ||||||
956 | sub rebuild | ||||||
957 | { | ||||||
958 | 43 | 43 | 1 | 169 | my ($parser, $command, $paragraph, $line_num) = @_; | ||
959 | |||||||
960 | 43 | 50 | 177 | if( $parser->{_verbose}>=VERBOSE_FULL ) | |||
961 | { | ||||||
962 | 0 | 0 | my $out = $$parser{_verbout}; | ||||
963 | 0 | 0 | print $out "scan done, rebuild...\n"; | ||||
964 | } | ||||||
965 | |||||||
966 | 43 | 492 | my %link_keys; | ||||
967 | my @link_ids; | ||||||
968 | 43 | 429 | delete $parser->{_linkwords}; | ||||
969 | 43 | 243 | delete $parser->{_linkwords_keys}; | ||||
970 | |||||||
971 | # build indices from "head"s. | ||||||
972 | # | ||||||
973 | 43 | 99 | foreach (@{$parser->{heads}}) | ||||
43 | 160 | ||||||
974 | { | ||||||
975 | 1 | 3 | my ($paraobj) = $$_[PARAINFO_PARAOBJ]; | ||||
976 | |||||||
977 | 1 | 50 | 25 | if( $paraobj->text() !~ /[^\w\s&]/ ) | |||
978 | { | ||||||
979 | 1 | 5 | $paraobj = $parser->_map_head_word($paraobj); | ||||
980 | 1 | 2 | $$_[PARAINFO_PARAOBJ] = $paraobj; | ||||
981 | } | ||||||
982 | |||||||
983 | 1 | 9 | my $id = $parser->makelinkanchor($paraobj); | ||||
984 | 1 | 6 | $id = $parser->addindex(\%link_keys,\@link_ids,$id,$paraobj); | ||||
985 | 1 | 6 | my $html = $parser->buildhtml($paraobj); | ||||
986 | |||||||
987 | 1 | 19 | my ($headsize) = $paraobj->cmd_name()=~/(\d)/; | ||||
988 | 1 | 10 | @$_[PARAINFO_CONTENT,PARAINFO_ID,PARAINFO_HEADSIZE] = ($html,$id,$headsize); | ||||
989 | } | ||||||
990 | |||||||
991 | # build indices from "item"s too. | ||||||
992 | # | ||||||
993 | 43 | 91 | foreach (@{$parser->{items}}) | ||||
43 | 204 | ||||||
994 | { | ||||||
995 | 0 | 0 | my ($paraobj,$listtype) = @$_[PARAINFO_PARAOBJ,PARAINFO_LISTTYPE]; | ||||
996 | |||||||
997 | 0 | 0 | 0 | $listtype ne 'dl' and next; | |||
998 | |||||||
999 | 0 | 0 | 0 | if( $paraobj->text() !~ /[^\w\s&]/ ) | |||
1000 | { | ||||||
1001 | 0 | 0 | $paraobj = $parser->_map_head_word($paraobj); | ||||
1002 | 0 | 0 | $$_[PARAINFO_PARAOBJ] = $paraobj; | ||||
1003 | } | ||||||
1004 | |||||||
1005 | 0 | 0 | my $id = $parser->makelinkanchor($paraobj); | ||||
1006 | 0 | 0 | $id = $parser->addindex(\%link_keys,\@link_ids,$id,$paraobj); | ||||
1007 | |||||||
1008 | 0 | 0 | $$_[PARAINFO_ID] = $id; | ||||
1009 | } | ||||||
1010 | |||||||
1011 | # find title block. | ||||||
1012 | # | ||||||
1013 | 43 | 170 | my $plain_title; | ||||
1014 | my $block_title; | ||||||
1015 | { | ||||||
1016 | # title is next of paragraph "=head |
||||||
1017 | # | ||||||
1018 | 43 | 74 | for( my $pos=0; $pos<@{$parser->{paras}}-1; ++$pos ) | ||||
43 | 115 | ||||||
85 | 308 | ||||||
1019 | { | ||||||
1020 | 43 | 206 | my $para = $parser->{paras}[$pos]; | ||||
1021 | # TODO: ID が NAME だったり 名前 だったり.. | ||||||
1022 | 43 | 50 | 33 | 256 | $para->[PARAINFO_TYPE]==PARA_HEAD && ($para->[PARAINFO_ID] =~ /^NAME/ || $para->[PARAINFO_ID] =~ /^Xe5X90X8dXe5X89X8d/ || $para->[PARAINFO_ID] eq 'X') | ||
66 | |||||||
1023 | or next; | ||||||
1024 | |||||||
1025 | # found "=head |
||||||
1026 | # title is next of it. | ||||||
1027 | # | ||||||
1028 | 1 | 3 | $para = $parser->{paras}[$pos+1]; | ||||
1029 | |||||||
1030 | 1 | 5 | ($plain_title,$block_title) = $parser->buildtitle($para->[PARAINFO_PARAOBJ]); | ||||
1031 | 1 | 2 | last; | ||||
1032 | } | ||||||
1033 | # if no title.. | ||||||
1034 | # | ||||||
1035 | 43 | 100 | 142 | if( !defined($plain_title) ) | |||
1036 | { | ||||||
1037 | 42 | 277 | $plain_title = 'untitled'; | ||||
1038 | } | ||||||
1039 | 43 | 100 | 156 | if( !defined($block_title) ) | |||
1040 | { | ||||||
1041 | 42 | 214 | my $cls = "$parser->{_cssprefix}title_block"; | ||||
1042 | 42 | 380 | $block_title = qq( \n$plain_title\n \n\n); |
||||
1043 | } | ||||||
1044 | } | ||||||
1045 | |||||||
1046 | 43 | 630 | $parser->{_outhtml_heading_toc} = $parser->buildhtml($parser->_map_head_word('TABLE OF CONTENTS')); | ||||
1047 | 43 | 461 | $parser->{_outhtml_heading_index} = $parser->buildhtml($parser->_map_head_word('INDEX')); | ||||
1048 | 43 | 509 | $parser->{_outhtml_plain_title} = $plain_title; | ||||
1049 | 43 | 118 | $parser->{_outhtml_block_title} = $block_title; | ||||
1050 | |||||||
1051 | # set link words. | ||||||
1052 | # | ||||||
1053 | 43 | 364 | $parser->{_linkwords} = \%link_keys; | ||||
1054 | } | ||||||
1055 | |||||||
1056 | # ----------------------------------------------------------------------------- | ||||||
1057 | # output_html | ||||||
1058 | # htmlを出力 | ||||||
1059 | # | ||||||
1060 | sub output_html | ||||||
1061 | { | ||||||
1062 | 43 | 43 | 1 | 101 | my ($parser, $command, $paragraph, $line_num) = @_; | ||
1063 | |||||||
1064 | 43 | 480 | my $out_fh = $parser->output_handle(); | ||||
1065 | |||||||
1066 | 43 | 50 | 162 | if( $parser->{_verbose}>=VERBOSE_FULL ) | |||
1067 | { | ||||||
1068 | 0 | 0 | $parser->vermbsg(VERBOSE_FULL,"ok, output...\n"); | ||||
1069 | } | ||||||
1070 | |||||||
1071 | #binmode($out_fh,":encoding($parser->{_out_charset})"); | ||||||
1072 | #print defined($out_fh)?"[$out_fh]\n":"{undef}\n"; | ||||||
1073 | 43 | 1930 | binmode($out_fh,":bytes"); | ||||
1074 | |||||||
1075 | 43 | 267 | my $plain_title = $parser->{_outhtml_plain_title}; | ||||
1076 | 43 | 96 | my $block_title = $parser->{_outhtml_block_title}; | ||||
1077 | 43 | 79 | my $made = $parser->{out_made}; | ||||
1078 | 43 | 184 | my $charset = $parser->{_out_charset}; | ||||
1079 | 43 | 80 | my $css = $parser->{out_css}; | ||||
1080 | 43 | 187 | my $xmllang = "ja-JP"; | ||||
1081 | 43 | 50 | 145 | defined($plain_title) or $plain_title = 'untitled'; | |||
1082 | 43 | 113 | my $cls = "$parser->{_cssprefix}title_block"; | ||||
1083 | 43 | 50 | 141 | defined($block_title) or $block_title = qq( \n$plain_title \n\n); |
|||
1084 | 43 | 100 | 4591 | if( $parser->{_in_charset} ne $parser->{_out_charset} ) | |||
1085 | { | ||||||
1086 | 20 | 104 | foreach($plain_title,$block_title,$made,$charset,$css) | ||||
1087 | { | ||||||
1088 | 100 | 100 | 456 | defined($_) or next; | |||
1089 | 60 | 351 | $_ = $parser->_from_to($_); | ||||
1090 | } | ||||||
1091 | } | ||||||
1092 | |||||||
1093 | # 出力開始 | ||||||
1094 | # | ||||||
1095 | 43 | 657 | print $out_fh qq(\n); | ||||
1096 | 43 | 741 | print $out_fh qq(\n); | ||||
1097 | 43 | 601 | print $out_fh qq(\n); | ||||
1098 | 43 | 443 | print $out_fh qq(\n); | ||||
1099 | 43 | 717 | print $out_fh qq( \n); | ||||
1100 | 43 | 50 | 521 | if( defined($css) ) | |||
1101 | { | ||||||
1102 | 0 | 0 | print $out_fh qq( \n); | ||||
1103 | 0 | 0 | print $out_fh qq( \n); | ||||
1104 | } | ||||||
1105 | #print $out_fh qq( \n); | ||||||
1106 | 43 | 169 | print $out_fh qq( |
||||
1107 | 43 | 50 | 744 | if( defined($made) ) | |||
1108 | { | ||||||
1109 | 0 | 0 | print $out_fh qq( \n); | ||||
1110 | } | ||||||
1111 | 43 | 126 | print $out_fh qq( \n); | ||||
1112 | 43 | 738 | print $out_fh qq( \n); | ||||
1113 | 43 | 409 | print $out_fh qq(\n); | ||||
1114 | 43 | 434 | print $out_fh qq(\n); | ||||
1115 | 43 | 487 | print $out_fh qq(\n); | ||||
1116 | |||||||
1117 | 43 | 358 | print $out_fh $block_title; | ||||
1118 | |||||||
1119 | # table of contents | ||||||
1120 | # | ||||||
1121 | 43 | 100 | 373 | if( @{$parser->{heads}} ) | |||
43 | 168 | ||||||
1122 | { | ||||||
1123 | 1 | 11 | my $heading = $parser->_from_to($parser->{_outhtml_heading_toc},'toc.heading'); | ||||
1124 | 1 | 4 | print $out_fh qq(\n); | ||||
1125 | 1 | 11 | print $out_fh qq( \n); |
||||
1126 | 1 | 10 | print $out_fh qq( \n$heading\n \n); |
||||
1127 | 1 | 9 | print $out_fh qq(
|
||||
1128 | 1 | 7 | my $curlevel = 0; | ||||
1129 | 1 | 10 | foreach (@{$parser->{heads}}) | ||||
1 | 3 | ||||||
1130 | { | ||||||
1131 | 1 | 3 | my ($text,$id,$headsize) = @$_[PARAINFO_CONTENT, | ||||
1132 | PARAINFO_ID, PARAINFO_HEADSIZE]; | ||||||
1133 | 1 | 4 | $text = $parser->_from_to($text,$_->[PARAINFO_PARAOBJ]); | ||||
1134 | 1 | 50 | 4 | if( !$curlevel ) | |||
0 | |||||||
0 | |||||||
1135 | { | ||||||
1136 | # 最初の1個. | ||||||
1137 | 1 | 1 | $curlevel = 1; | ||||
1138 | }elsif( $curlevel==$headsize ) | ||||||
1139 | { | ||||||
1140 | # 同じレベル. | ||||||
1141 | 0 | 0 | print $out_fh qq(\n); | ||||
1142 | }elsif( $curlevel<$headsize ) | ||||||
1143 | { | ||||||
1144 | # レベル増加. | ||||||
1145 | 0 | 0 | print $out_fh qq(
|
||||
1146 | 0 | 0 | ++$curlevel; | ||||
1147 | 0 | 0 | print $out_fh qq(
|
||||
1148 | 0 | 0 | $curlevel=$headsize; | ||||
1149 | }else | ||||||
1150 | { | ||||||
1151 | # レベル減少. | ||||||
1152 | 0 | 0 | print $out_fh qq(\n).(qq(\n\n)x($curlevel-$headsize)); | ||||
1153 | 0 | 0 | $curlevel = $headsize; | ||||
1154 | } | ||||||
1155 | 1 | 8 | print $out_fh qq( |
||||
1156 | } | ||||||
1157 | 1 | 15 | print $out_fh qq(\n\n)x$curlevel; | ||||
1158 | 1 | 8 | print $out_fh qq(\n); | ||||
1159 | 1 | 15 | print $out_fh qq(\n); | ||||
1160 | 1 | 8 | print $out_fh qq(\n); | ||||
1161 | } | ||||||
1162 | |||||||
1163 | # 本文の出力. | ||||||
1164 | 43 | 235 | my $in_item = 0; | ||||
1165 | 43 | 75 | my $first_item = 1; | ||||
1166 | 43 | 86 | my @verbpack; | ||||
1167 | my @blockstack; | ||||||
1168 | 6 | 6 | 88 | use constant {STK_PARAOBJ=>0,STK_BEHAVIOR=>1,}; | |||
6 | 15 | ||||||
6 | 731 | ||||||
1169 | 6 | 6 | 33 | use constant {BHV_NONE=>'none',BHV_NORMAL=>'normal',BHV_VERBATIM=>'verbatim',BHV_IGNORE=>'ignore'}; | |||
6 | 18 | ||||||
6 | 23190 | ||||||
1170 | 43 | 295 | print $out_fh qq(\n); | ||||
1171 | 43 | 451 | foreach (@{$parser->{paras}}) | ||||
43 | 156 | ||||||
1172 | { | ||||||
1173 | 86 | 468 | my ($paratype,$paraobj) = @$_[PARAINFO_TYPE,PARAINFO_PARAOBJ]; | ||||
1174 | 86 | 190 | $parser->{_iseqstack} = []; | ||||
1175 | |||||||
1176 | # ignore 状態の確認 | ||||||
1177 | # | ||||||
1178 | 86 | 50 | 396 | if( grep{$_->[STK_BEHAVIOR]eq BHV_IGNORE}@blockstack ) | |||
0 | 0 | ||||||
1179 | { | ||||||
1180 | #print $out_fh " in ignore ...\n"; | ||||||
1181 | 0 | 0 | 0 | 0 | if( $paratype==PARA_END | ||
1182 | && $_->[PARAINFO_CONTENT] eq $blockstack[-1]->[STK_PARAOBJ][PARAINFO_CONTENT] ) | ||||||
1183 | { | ||||||
1184 | 0 | 0 | my $fin = pop(@blockstack); | ||||
1185 | 0 | 0 | my $mode = $_->[PARAINFO_CONTENT]; | ||||
1186 | 0 | 0 | my $outtext = "\n"; | ||||
1187 | 0 | 0 | print $out_fh $parser->_from_to($outtext); | ||||
1188 | } | ||||||
1189 | 0 | 0 | next; | ||||
1190 | } | ||||||
1191 | |||||||
1192 | # 連続する verbose の連結処理. | ||||||
1193 | # | ||||||
1194 | 86 | 0 | 0 | 0 | 823 | my $blk = first{(ref($_)||'')eq'ARRAY'&&$$_[STK_BEHAVIOR]ne BHV_IGNORE}reverse @blockstack; | |
0 | 0 | ||||||
1195 | 86 | 50 | 33 | 1527 | if( $paratype==PARA_VERBATIM || ($paratype!=PARA_END&&$blk&&$blk->[STK_BEHAVIOR]eq BHV_VERBATIM) ) | ||
50 | 33 | ||||||
33 | |||||||
1196 | { | ||||||
1197 | 0 | 0 | my $text = $parser->escapeHtml($paraobj->text()); | ||||
1198 | 0 | 0 | $text = $parser->_from_to($text); | ||||
1199 | 0 | 0 | 0 | $text !~ /^\n*$/ and push(@verbpack,$text); | |||
1200 | 0 | 0 | next; | ||||
1201 | }elsif( @verbpack ) | ||||||
1202 | { | ||||||
1203 | 0 | 0 | my $text = join('',@verbpack); | ||||
1204 | 0 | 0 | $text =~ s/\s*$//; | ||||
1205 | 0 | 0 | 0 | if( $text !~ /^\n*$/ ) | |||
1206 | { | ||||||
1207 | 0 | 0 | $text =~ s/\n+$/\n/; | ||||
1208 | 0 | 0 | my $outtext = qq( \n\n); |
||||
1209 | 0 | 0 | print $out_fh $outtext; | ||||
1210 | } | ||||||
1211 | 0 | 0 | @verbpack = (); | ||||
1212 | } | ||||||
1213 | |||||||
1214 | # 普通に出力処理. | ||||||
1215 | # $outtext には _from_to 済みのテキストを追加. | ||||||
1216 | # | ||||||
1217 | 86 | 271 | my $outtext; | ||||
1218 | 86 | 100 | 717 | if( $paratype==PARA_TEXTBLOCK ) | |||
100 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
50 | |||||||
0 | |||||||
1219 | { | ||||||
1220 | 43 | 203 | my $text = $parser->buildhtml($paraobj); | ||||
1221 | 43 | 1119 | $text = $parser->_from_to($text); | ||||
1222 | 43 | 50 | 556 | $text =~ /^\s*$/ and next; | |||
1223 | 43 | 134 | $outtext = " \n$text\n \n\n"; |
||||
1224 | }elsif( $paratype==PARA_HEAD ) | ||||||
1225 | { | ||||||
1226 | 1 | 9 | $outtext = ''; | ||||
1227 | 1 | 50 | 4 | if( @blockstack ) | |||
1228 | { | ||||||
1229 | 0 | 0 | foreach(@blockstack) | ||||
1230 | { | ||||||
1231 | 0 | 0 | 0 | if( ref($_)eq'ARRAY' ) | |||
1232 | { | ||||||
1233 | 0 | 0 | 0 | if( $_->[PARAINFO_TYPE]==PARA_OVER ) | |||
1234 | { | ||||||
1235 | 0 | 0 | my ($type) = $_->[PARAINFO_LISTTYPE]; | ||||
1236 | 0 | 0 | 0 | $type eq 'dl' and $outtext .= ""; | |||
1237 | 0 | 0 | $outtext .= "$type> \n\n"; | ||||
1238 | } | ||||||
1239 | }else | ||||||
1240 | { | ||||||
1241 | 0 | 0 | my $type = $_; | ||||
1242 | 0 | 0 | 0 | $type eq 'dl' and $outtext .= ""; | |||
1243 | 0 | 0 | $outtext .= "$type> \n\n"; | ||||
1244 | } | ||||||
1245 | } | ||||||
1246 | 0 | 0 | $#blockstack = -1; | ||||
1247 | 0 | 0 | $first_item = 1; | ||||
1248 | } | ||||||
1249 | 1 | 3 | my ($text,$id,$headsize) = @$_[PARAINFO_CONTENT,PARAINFO_ID,PARAINFO_HEADSIZE]; | ||||
1250 | 1 | 3 | my $tag = "h$headsize"; | ||||
1251 | 1 | 4 | $text = $parser->_from_to($text); | ||||
1252 | 1 | 50 | 7 | $headsize==1 and $outtext .= qq(\n \n); |
|||
1253 | 1 | 4 | $outtext .= qq(<$tag>\n$text$tag>\n\n); | ||||
1254 | }elsif( $paratype==PARA_OVER ) | ||||||
1255 | { | ||||||
1256 | 0 | 0 | my ($type) = $_->[PARAINFO_LISTTYPE]; | ||||
1257 | 0 | 0 | $outtext = ''; | ||||
1258 | 0 | 0 | 0 | if( defined($type) ) | |||
1259 | { | ||||||
1260 | 0 | 0 | $outtext .= "<$type>\n"; | ||||
1261 | }else | ||||||
1262 | { | ||||||
1263 | 0 | 0 | warn "over type unknown, using ul"; | ||||
1264 | 0 | 0 | $type = 'ul'; | ||||
1265 | 0 | 0 | $outtext .= "\n"; | ||||
1266 | 0 | 0 | $outtext .= "<$type>\n"; | ||||
1267 | } | ||||||
1268 | 0 | 0 | $first_item = 1; | ||||
1269 | 0 | 0 | my @stk; | ||||
1270 | 0 | 0 | @stk[STK_PARAOBJ,STK_BEHAVIOR] = ($_,BHV_NORMAL); | ||||
1271 | 0 | 0 | push(@blockstack,\@stk); | ||||
1272 | }elsif( $paratype==PARA_BACK ) | ||||||
1273 | { | ||||||
1274 | 0 | 0 | my ($type) = @$_[PARAINFO_LISTTYPE]; | ||||
1275 | 0 | 0 | $outtext = ''; | ||||
1276 | 0 | 0 | 0 | if( $in_item ) | |||
1277 | { | ||||||
1278 | 0 | 0 | 0 | $outtext = $type eq 'dl' ? "\n" : "\n"; | |||
1279 | 0 | 0 | --$in_item; | ||||
1280 | } | ||||||
1281 | 0 | 0 | $outtext .= "$type>\n\n"; | ||||
1282 | 0 | 0 | pop(@blockstack); | ||||
1283 | }elsif( $paratype==PARA_ITEM ) | ||||||
1284 | { | ||||||
1285 | 0 | 0 | my ($type,$id) = @$_[PARAINFO_LISTTYPE,PARAINFO_ID]; | ||||
1286 | 0 | 0 | $outtext = ''; | ||||
1287 | 0 | 0 | 0 | if( !@blockstack ) | |||
1288 | { | ||||||
1289 | 0 | 0 | push(@blockstack,$type); | ||||
1290 | 0 | 0 | $outtext = qq(<$type> \n); | ||||
1291 | } | ||||||
1292 | 0 | 0 | 0 | 0 | if( $type eq 'ul' || $type eq 'ol' ) | ||
0 | |||||||
1293 | { | ||||||
1294 | 0 | 0 | 0 | $first_item or $outtext .= "\n"; | |||
1295 | 0 | 0 | $outtext .= qq( |
||||
1296 | }elsif( $type eq 'dl' ) | ||||||
1297 | { | ||||||
1298 | 0 | 0 | my $bak = delete $parser->{_linkwords}; | ||||
1299 | 0 | 0 | my $item = $parser->buildhtml($paraobj); | ||||
1300 | 0 | 0 | $parser->{_linkwords} = $bak; | ||||
1301 | 0 | 0 | $item =~ s/^\s+//; | ||||
1302 | 0 | 0 | $item =~ s/\s+$//; | ||||
1303 | 0 | 0 | $item = $parser->_from_to($item); | ||||
1304 | 0 | 0 | 0 | $first_item or $outtext .= "\n"; | |||
1305 | 0 | 0 | $outtext .= qq( |
||||
1306 | 0 | 0 | $outtext .= qq( |
||||
1307 | }else | ||||||
1308 | { | ||||||
1309 | 0 | 0 | $parser->vermsg(VERBOSE_ERROR,"unknown list type [$type]"); | ||||
1310 | } | ||||||
1311 | 0 | 0 | 0 | $first_item and undef($first_item),++$in_item; | |||
1312 | }elsif( $paratype==PARA_BEGIN ) | ||||||
1313 | { | ||||||
1314 | 0 | 0 | my @stk; | ||||
1315 | 0 | 0 | @stk[STK_PARAOBJ,STK_BEHAVIOR] = ($_,BHV_IGNORE); | ||||
1316 | 0 | 0 | push(@blockstack,\@stk); | ||||
1317 | 0 | 0 | my $mode = $_->[PARAINFO_CONTENT]; | ||||
1318 | 0 | 0 | 0 | if( $mode eq 'html' ) | |||
0 | |||||||
1319 | { | ||||||
1320 | 0 | 0 | $outtext .= "\n"; | ||||
1321 | 0 | 0 | $stk[STK_BEHAVIOR] = BHV_NORMAL; | ||||
1322 | }elsif( $mode eq 'text' ) | ||||||
1323 | { | ||||||
1324 | 0 | 0 | $outtext .= "\n"; | ||||
1325 | 0 | 0 | $stk[STK_BEHAVIOR] = BHV_VERBATIM; | ||||
1326 | }else | ||||||
1327 | { | ||||||
1328 | 0 | 0 | $outtext .= "\n"; | ||||
1329 | } | ||||||
1330 | }elsif( $paratype==PARA_END ) | ||||||
1331 | { | ||||||
1332 | 0 | 0 | my $fin = pop(@blockstack); | ||||
1333 | 0 | 0 | my $mode = $_->[PARAINFO_CONTENT]; | ||||
1334 | 0 | 0 | $outtext .= "\n"; | ||||
1335 | }elsif( $paratype==PARA_FOR ) | ||||||
1336 | { | ||||||
1337 | }elsif( $paratype==PARA_ENCODING ) | ||||||
1338 | { | ||||||
1339 | 0 | 0 | my $text = $_->[PARAINFO_CONTENT]; | ||||
1340 | 0 | 0 | my $cmd = $paraobj->cmd_name(); | ||||
1341 | 0 | 0 | $text = $parser->_from_to($text); | ||||
1342 | 0 | 0 | $text =~ s/\n(\s*\n)+/\n/g; | ||||
1343 | 0 | 0 | $outtext = "\n"; | ||||
1344 | }elsif( $paratype==PARA_POD ) | ||||||
1345 | { | ||||||
1346 | }elsif( $paratype==PARA_CUT ) | ||||||
1347 | { | ||||||
1348 | }else | ||||||
1349 | { | ||||||
1350 | 0 | 0 | $parser->verbmsg(VERBOSE_ERROR,"what\'s got?? [$paratype]"); | ||||
1351 | 0 | 0 | next; | ||||
1352 | } | ||||||
1353 | 86 | 100 | 396 | if( defined($outtext) ) | |||
1354 | { | ||||||
1355 | # $outtext は _from_to 済み. | ||||||
1356 | 44 | 445 | print $out_fh $outtext; | ||||
1357 | } | ||||||
1358 | } | ||||||
1359 | 43 | 50 | 695 | if( @verbpack ) | |||
1360 | { | ||||||
1361 | 0 | 0 | my $text = join('',@verbpack); | ||||
1362 | 0 | 0 | 0 | if( $text !~ /^\n*$/ ) | |||
1363 | { | ||||||
1364 | 0 | 0 | my $outtext = qq( \n\n); |
||||
1365 | 0 | 0 | $outtext = $parser->_from_to($outtext); | ||||
1366 | 0 | 0 | print $out_fh $outtext; | ||||
1367 | } | ||||||
1368 | } | ||||||
1369 | 43 | 482 | print $out_fh qq(\n); | ||||
1370 | 43 | 480 | print $out_fh qq(\n); | ||||
1371 | |||||||
1372 | 43 | 545 | print $out_fh $block_title; | ||||
1373 | |||||||
1374 | # 索引 | ||||||
1375 | # | ||||||
1376 | { | ||||||
1377 | 43 | 679 | my $heading = $parser->_from_to($parser->{_outhtml_heading_index}); | ||||
43 | 1386 | ||||||
1378 | 43 | 232 | print $out_fh qq(\n); | ||||
1379 | 43 | 450 | print $out_fh qq( \n); |
||||
1380 | 43 | 442 | print $out_fh qq($heading\n); |
||||
1381 | 43 | 583 | print $out_fh qq( \n); |
||||
1382 | 43 | 456 | print $out_fh qq(
|
||||
1383 | 43 | 352 | foreach(sort keys %{$parser->{_linkwords}}) | ||||
43 | 305 | ||||||
1384 | { | ||||||
1385 | #my ($text,$id) = ($parser->escapeHtml($_),$parser->{_linkwords}{$_}); | ||||||
1386 | 2 | 12 | my ($text,$id) = ($_,$parser->{_linkwords}{$_}); | ||||
1387 | 2 | 6 | $text = $parser->_from_to($text); | ||||
1388 | 2 | 8 | print $out_fh qq( |
||||
1389 | } | ||||||
1390 | 43 | 485 | print $out_fh qq(\n); | ||||
1391 | 43 | 437 | print $out_fh qq(\n); | ||||
1392 | 43 | 411 | print $out_fh qq(\n); | ||||
1393 | 43 | 410 | print $out_fh qq(\n); | ||||
1394 | |||||||
1395 | 43 | 366 | print $out_fh $block_title; | ||||
1396 | } | ||||||
1397 | |||||||
1398 | 43 | 1622 | print $out_fh qq(\n); | ||||
1399 | 43 | 534 | print $out_fh qq(\n); | ||||
1400 | } | ||||||
1401 | |||||||
1402 | # ============================================================================= | ||||||
1403 | # ユーティリティ関数群 | ||||||
1404 | # ============================================================================= | ||||||
1405 | |||||||
1406 | # ----------------------------------------------------------------------------- | ||||||
1407 | # $text = $this->escapeHtml($text); | ||||||
1408 | # html に埋め込めれる用にエスケープ | ||||||
1409 | # | ||||||
1410 | sub escapeHtml | ||||||
1411 | { | ||||||
1412 | 168 | 168 | 1 | 542 | my @list = @_[1..$#_]; | ||
1413 | 168 | 50 | 575 | wantarray or @list = shift @list; | |||
1414 | 168 | 304 | foreach(@list) | ||||
1415 | { | ||||||
1416 | 168 | 50 | 679 | defined($_) or next; | |||
1417 | 168 | 50 | 685 | s/([&<>\"])/$1 eq '&' ? '&' | |||
2 | 50 | 28 | |||||
50 | |||||||
1418 | : $1 eq '<' ? '<' | ||||||
1419 | : $1 eq '>' ? '>' | ||||||
1420 | : '"' /ge; | ||||||
1421 | } | ||||||
1422 | 168 | 50 | 846 | @list!=1?@list:$list[0]; | |||
1423 | } | ||||||
1424 | |||||||
1425 | # ----------------------------------------------------------------------------- | ||||||
1426 | # $text = $this->unescapeHtml($text); | ||||||
1427 | # escapeHtml によって実体参照に変換された文字を通常の文字に戻す. | ||||||
1428 | # | ||||||
1429 | sub unescapeHtml | ||||||
1430 | { | ||||||
1431 | 0 | 0 | 1 | 0 | my @list = @_[1..$#_]; | ||
1432 | 0 | 0 | 0 | wantarray or @list = shift @list; | |||
1433 | 0 | 0 | foreach(@list) | ||||
1434 | { | ||||||
1435 | 0 | 0 | 0 | s/&(lt|gt|amp|quot);/$1 eq 'amp' ? '&' | |||
0 | 0 | 0 | |||||
0 | |||||||
1436 | : $1 eq 'lt' ? '<' | ||||||
1437 | : $1 eq 'gt' ? '>' | ||||||
1438 | : '"' /ge; | ||||||
1439 | } | ||||||
1440 | 0 | 0 | 0 | @list!=1?@list:$list[0]; | |||
1441 | } | ||||||
1442 | |||||||
1443 | # ----------------------------------------------------------------------------- | ||||||
1444 | # $text = $this->escapeUrl($text); | ||||||
1445 | # url に埋め込めれる用にエスケープ | ||||||
1446 | # | ||||||
1447 | sub escapeUrl | ||||||
1448 | { | ||||||
1449 | 4 | 4 | 1 | 16 | my @list = @_[1..$#_]; | ||
1450 | 4 | 50 | 17 | wantarray or @list = $list[0]; | |||
1451 | 4 | 9 | foreach(@list) | ||||
1452 | { | ||||||
1453 | 4 | 18 | s/([^a-zA-Z0-9\-\_\.\!\~\*\'\(\)\/])/sprintf('%%%02x',unpack("C",$1))/eg; | ||||
0 | 0 | ||||||
1454 | } | ||||||
1455 | 4 | 50 | 21 | @list!=1?@list:$list[0]; | |||
1456 | } | ||||||
1457 | |||||||
1458 | # ----------------------------------------------------------------------------- | ||||||
1459 | # $text = $this->resolvePodEscape($text); | ||||||
1460 | # E<> の中身を html な実体参照に変換. | ||||||
1461 | # | ||||||
1462 | sub resolvePodEscape | ||||||
1463 | { | ||||||
1464 | 12 | 12 | 1 | 43 | my @list = @_[1..$#_]; | ||
1465 | 12 | 50 | 43 | wantarray or @list = shift @list; | |||
1466 | 12 | 26 | foreach(@list) | ||||
1467 | { | ||||||
1468 | 12 | 100 | 186 | if( $_ eq 'lt' ) | |||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
1469 | { | ||||||
1470 | 1 | 5 | $_ = '<'; | ||||
1471 | }elsif( $_ eq 'gt' ) | ||||||
1472 | { | ||||||
1473 | 1 | 11 | $_ = '>'; | ||||
1474 | }elsif( $_ eq 'verbar' ) | ||||||
1475 | { | ||||||
1476 | 1 | 10 | $_ = '|'; | ||||
1477 | }elsif( $_ eq 'sol' ) | ||||||
1478 | { | ||||||
1479 | 1 | 13 | $_ = '/'; | ||||
1480 | }elsif( $_ =~ /^0x([0-9a-fA-F]+)$/ ) | ||||||
1481 | { | ||||||
1482 | 2 | 17 | $_ = "$1;"; | ||||
1483 | }elsif( $_ =~ /^0([0-7]+)$/ ) | ||||||
1484 | { | ||||||
1485 | 2 | 33 | $_ = "".oct($1).";"; | ||||
1486 | }elsif( $_ =~ /^\d+$/ ) | ||||||
1487 | { | ||||||
1488 | 2 | 22 | $_ = "$_;"; | ||||
1489 | }else | ||||||
1490 | { | ||||||
1491 | 2 | 13 | $_ = "&$_;"; | ||||
1492 | } | ||||||
1493 | } | ||||||
1494 | 12 | 50 | 63 | wantarray?@list:$list[0]; | |||
1495 | } | ||||||
1496 | # ----------------------------------------------------------------------------- | ||||||
1497 | # $text = $parser->resolveLink($text); | ||||||
1498 | # | ||||||
1499 | sub resolveLink | ||||||
1500 | { | ||||||
1501 | 0 | 0 | 1 | my ($parser,@list) = @_; | |||
1502 | 0 | 0 | @list = $parser->unescapeHtml(wantarray?@list:shift @list); | ||||
1503 | 0 | foreach(@list) | |||||
1504 | { | ||||||
1505 | 0 | 0 | if( /^\w+:[^:]/ ) | ||||
1506 | { | ||||||
1507 | 0 | my $link_to = $parser->escapeHtml($_); | |||||
1508 | 0 | $_ = qq($_); | |||||
1509 | }else | ||||||
1510 | { | ||||||
1511 | 0 | my ($text,$target,$sec); | |||||
1512 | 0 | 0 | if( /^"(.*)"$/ ) | ||||
1513 | { | ||||||
1514 | 0 | ($text,$target,$sec) = ('','',$1); | |||||
1515 | }else | ||||||
1516 | { | ||||||
1517 | 0 | 0 | $text = s/^([^\/\|]*)\|// ? $1 : ''; | ||||
1518 | 0 | 0 | $target = s/^([^\/\|]*)\/?// ? $1 : ''; | ||||
1519 | 0 | ($sec = $_) =~ s/^\"(.*)\"$/$1/; | |||||
1520 | } | ||||||
1521 | 0 | 0 | my $lang = $parser->{_expandlangs}[0]||$parser->{_defaultlang} || DEFAULT_LANG; | ||||
1522 | 0 | return $parser->makelink($lang,$text,$target,$sec); | |||||
1523 | } | ||||||
1524 | } | ||||||
1525 | 0 | 0 | wantarray?@list:$list[0]; | ||||
1526 | } | ||||||
1527 | |||||||
1528 | 1; | ||||||
1529 | __END__ |