1# text2pdf.pl - simple PDFJ sample script 2# 2004 <nakajima@netstock.co.jp> 3# perl text2pdf.pl INFILE OUTFILE 4 5use PDFJ 'EUC'; 6 7use Getopt::Std; 8use strict; 9 10my @KutenEUC = ("\xa1\xa3", "\xa1\xa5", "\xa1\xa2", "\xa1\xa4"); 11 12my %Opt; 13getopts 'sec:', \%Opt; 14my($InFile, $OutFile) = @ARGV; 15$OutFile ||= "$InFile.pdf"; 16 17my %Cfg; 18readcfgfile("$0.cfg", \%Cfg); 19readcfgfile($Opt{c}, \%Cfg) if $Opt{c}; 20 21my $TextCode = 22 $Opt{s} ? 'SJIS' : 23 $Opt{e} ? 'EUC' : 24 $Cfg{TextCode}; 25 26my $Encoding = $PDFJ::Default{Jcode} eq 'SJIS' ? $Cfg{EncodingSJIS} : $Cfg{EncodingEUC}; 27my $Linewidth = $Cfg{Pagesize}[0] - $Cfg{Margin}[0] - $Cfg{Margin}[1]; 28my $PageHeight = $Cfg{Pagesize}[1] - $Cfg{Margin}[2] - $Cfg{Margin}[3]; 29my @PosBody = ($Cfg{Margin}[0], $Cfg{Pagesize}[1] - $Cfg{Margin}[3]); 30my @PosHeader = ($Cfg{Margin}[0], $Cfg{Pagesize}[1] - $Cfg{Margin}[3] + 31 $Cfg{Margin}[2] / 2); 32my @PosFooter = ($Cfg{Margin}[0], $Cfg{Margin}[3] / 2); 33my $Time = scalar(localtime); 34 35my(%Font, %TStyle, %PStyle, %Sptn); 36 37my $Doc = PDFJ::Doc->new(1.2, @{$Cfg{Pagesize}}); 38 39for my $name(qw(Body Fixed Header Footer)) { 40 setparaspec($name, $Cfg{"${name}Spec"}); 41} 42for my $name(qw(Subtitle1 Subtitle2 Subtitle3 Subtitle4)) { 43 setparaspec($name, $Cfg{"${name}Spec"}, 1); 44} 45for( my $j = 1; $j <= $Cfg{Titles}; $j++ ) { 46 my $name = "Title$j"; 47 setparaspec($name, $Cfg{"${name}Spec"}); 48} 49if( ref($Cfg{SpecialTitleSpec}) eq 'HASH' ) { 50 my $sptnnum = 0; 51 for my $ptn(keys %{$Cfg{SpecialTitleSpec}}) { 52 $Sptn{$ptn} = $sptnnum; 53 setparaspec("Special$sptnnum", $Cfg{SpecialTitleSpec}{$ptn}); 54 $sptnnum++; 55 } 56} 57my $BodyLineFeed = $PStyle{Body}{linefeed}; 58if( $BodyLineFeed =~ /^(\d+)%/ ) { 59 $BodyLineFeed = $TStyle{Body}{fontsize} * $1 / 100; 60} 61 62my $EmptyLineSkip = $Cfg{EmptyLineSkip} || $BodyLineFeed; 63 64my @tmp; 65open F, $InFile or die; 66while(<F>) { 67 s/\r\n/\n/; 68 chomp; 69 if( $TextCode eq 'SJIS' ) { 70 $_ = sjis2euc($_); 71 } 72 if( /^\s*$/ ) { 73 if( @tmp ) { 74 if( ref($tmp[$#tmp]) eq 'T2P::Empty' ) { 75 ${$tmp[$#tmp]}++; 76 } else { 77 my $work = 1; 78 push @tmp, bless(\$work, 'T2P::Empty'); 79 } 80 } 81 } elsif( /^\S/ && /\S$/ && !/ / && 82 (!@tmp || ref($tmp[$#tmp]) eq 'T2P::Empty' || 83 ref($tmp[$#tmp]) eq 'T2P::Title') && 84 length($_) <= $Cfg{TitleMaxlen} && !lastiskuten($_) ) { 85 if( @tmp && ref($tmp[$#tmp]) eq 'T2P::Title' ) { 86 if( islabeled($_) ) { 87 my $last = pop @tmp; 88 push @tmp, @$last; 89 push @tmp, $_; 90 } else { 91 push @{$tmp[$#tmp]}, $_; 92 } 93 } else { 94 push @tmp, bless([$_], 'T2P::Title'); 95 } 96 } else { 97 if( @tmp && ref($tmp[$#tmp]) eq 'T2P::Title' ) { 98 my $last = pop @tmp; 99 push @tmp, @$last; 100 } 101 push @tmp, $_; 102 } 103} 104close F; 105 106my @objects; 107my $titles = 0; 108for( my $j = 0; $j < @tmp; $j++ ) { 109 local($_) = $tmp[$j]; 110 if( ref($_) eq 'T2P::Empty' ) { 111 if( $j > 0 && !ref($tmp[$j - 1]) && $j < $#tmp && !ref($tmp[$j + 1]) ) { 112 push @objects, BlockSkip($EmptyLineSkip * $$_); 113 } 114 } elsif( ref($_) eq 'T2P::Title' ) { 115 my $ttxt = join("\n", @$_); 116 my $special = 0; 117 for my $ptn(keys %Sptn) { 118 if( $ttxt =~ /$ptn/s ) { 119 push @objects, para("Special$Sptn{$ptn}", 0, 0, @$_); 120 $special = 1; 121 last; 122 } 123 } 124 next if $special; 125 $titles++; 126 if( $titles <= $Cfg{Titles} ) { 127 push @objects, para("Title$titles", 0, 0, @$_); 128 } else { 129 my $num = 1; 130 if( ref($tmp[$j - 1]) eq 'T2P::Empty' ) { 131 $num = ${$tmp[$j - 1]}; 132 $num = 4 if $num > 4; 133 } 134 push @objects, para("Subtitle$num", 0, 0, @$_); 135 } 136 } else { 137 my $fixed = /^ /; 138 $_ = expandtab($_, $Cfg{Tabwidth}); 139 my $indent = 0; 140 if( s/^ +// ) { 141 $indent = $TStyle{Body}{fontsize} / 2 * length($&); 142 } 143 my $paraname = $fixed ? "Fixed" : "Body"; 144 push @objects, para($paraname, 0, $indent, $_); 145 } 146} 147 148for my $block( Block('V', \@objects, BStyle())->break($PageHeight) ) { 149 my $page = $Doc->new_page; 150 print "page ",$page->pagenum,"\n"; 151 $block->show($page, @PosBody); 152 my $htext = $Cfg{Header}; 153 my $header = Paragraph(Text(headerfooter($page, $Cfg{Header}), 154 $TStyle{Header}), $PStyle{Header}); 155 $header->show($page, @PosHeader); 156 my $footer = Paragraph(Text(headerfooter($page, $Cfg{Footer}), 157 $TStyle{Footer}), $PStyle{Footer}); 158 $footer->show($page, @PosFooter); 159} 160$Doc->print($OutFile); 161 162sub islabeled { 163 local($_) = @_; 164 for my $mark(@{$Cfg{ItemMark}}) { 165 if( s/^\Q$mark\E// ) { 166 return 1; 167 } 168 } 169 for my $ptn(@{$Cfg{EnumPattern}}) { 170 if( s/^$ptn// ) { 171 return 1; 172 } 173 } 174 if( /\t/ ) { 175 return 1; 176 } 177 0; 178} 179 180sub picklabel { 181 local($_) = @_; 182 my $label = ''; 183 my($labelsize, $labelskip) = (0, 0); 184 for my $mark(@{$Cfg{ItemMark}}) { 185 if( s/^\Q$mark\E// ) { 186 $label = $mark; 187 return ($label, $_, @{$Cfg{ItemLabelspec}}); 188 } 189 } 190 for my $ptn(@{$Cfg{EnumPattern}}) { 191 if( s/^$ptn// ) { 192 $label = $&; 193 return ($label, $_, @{$Cfg{EnumLabelspec}}); 194 } 195 } 196 if( /\t/ ) { 197 return ($`, $', @{$Cfg{DescLabelspec}}); 198 } 199 ($label, $_, $labelsize, $labelskip); 200} 201 202sub expandtab { 203 my($str, $tabwidth) = @_; 204 while( $str =~ s/^( *)\t/$1.(' ' x ($tabwidth - length($1) % $tabwidth))/e ) 205 {} 206 $str; 207} 208 209sub _para { 210 my($pstyle, $tstyle, $size, $indent, $label, $labelsize, $labelskip, @texts) 211 = @_; 212 if( $size ) { 213 $pstyle = $pstyle->clone(size => $size, beginpadding => 0); 214 } 215 if( $indent ) { 216 $pstyle = $pstyle->clone(beginpadding => 217 $pstyle->{beginpadding} + $indent); 218 } 219 if( $label ne '' ) { 220 $pstyle = $pstyle->clone(labeltext => $label, labelsize => $labelsize, 221 labelskip => $labelskip); 222 } 223 Paragraph(Text(\@texts, $tstyle), $pstyle); 224} 225 226sub para { 227 my($name, $size, $indent, @texts) = @_; 228 die "missing texts for paragraph" unless @texts; 229 my($label, $labelsize, $labelskip); 230 ($label, $texts[0], $labelsize, $labelskip) = picklabel($texts[0]); 231 for( my $j = 0; $j < @texts - 1; $j += 2 ) { 232 splice @texts, $j + 1, 0, NewLine; 233 } 234 if( $name eq 'Fixed' ) { 235 @texts = map {ref($_) ? $_ : space2hankaku($_)} @texts; 236 } 237 my $pstyle = $PStyle{$name}; 238 my $tstyle = $TStyle{$name}; 239 die "missing Spec for '$name'" unless $pstyle && $tstyle; 240 if( $name eq 'Fixed' ) { 241 $tstyle->{noglue} = 1; 242 $tstyle->{noshift} = 1; 243 } 244 _para($pstyle, $tstyle, $size, $indent, $label, $labelsize, $labelskip, 245 @texts); 246} 247 248sub space2hankaku { 249 my($str) = @_; 250 my @result; 251 while( $str =~ / +/ ) { 252 $str = $'; 253 push @result, $` if $` ne ''; 254 push @result, Space($Cfg{FixedSpec}[2] / 2 * length($&)); 255 } 256 push @result, $str if $str ne ''; 257 @result; 258} 259 260sub setparaspec { 261 my($name, $spec, $postnobreak) = @_; 262 $Font{$name} = $spec->[1] ? 263 $Doc->new_font($spec->[0], $Encoding, $spec->[1], 'WinAnsiEncoding', 264 1.05) : 265 $Doc->new_font($spec->[0], $Encoding); 266 $TStyle{$name} = TStyle(font => $Font{$name}, fontsize => $spec->[2]); 267 my $indent = $spec->[5] * $TStyle{$name}{fontsize} / 2; 268 $PStyle{$name} = defined $spec->[6] ? 269 PStyle(size => $Linewidth, linefeed => $spec->[3], 270 align => $spec->[4], beginpadding => $indent, 271 preskip => $spec->[6], postskip => $spec->[7]) : 272 PStyle(size => $Linewidth, linefeed => $spec->[3], 273 align => $spec->[4], beginpadding => $indent); 274 $PStyle{$name}{postnobreak} = 1 if $postnobreak; 275} 276 277sub headerfooter { 278 my($page, $spec) = @_; 279 $spec =~ s/%t/$Time/g; 280 $spec =~ s/%f/$InFile/g; 281 $spec =~ s/%p/$page->pagenum/ge; 282 $spec; 283} 284 285# cfgfile must be EUC 286sub readcfgfile { 287 my($cfgfile, $cfg) = @_; 288 my($invalue, $endmark, $key, $value); 289 my $F = new FileHandle; 290 291 open $F, $cfgfile or die "cannot open $cfgfile"; 292 $invalue = 0; 293 while(<$F>) { 294 s/\r\n/\n/; 295 if( $invalue ) { 296 if( /^$endmark$/ ) { 297 $invalue = 0; 298 } else { 299 $cfg->{$key} .= $_; 300 } 301 } elsif( /^(\w+)\s*=\s*(.+)/ ) { 302 $key = $1; 303 $value = $2; 304 if( $value =~ /^<<(.+)/ ) { 305 $endmark = $1; 306 $invalue = 1; 307 } else { 308 $cfg->{$key} = $value; 309 } 310 } 311 } 312 close($F); 313 for my $key(keys %$cfg) { 314 my $value = $cfg->{$key}; 315 if( $value =~ /^\"/ && $value =~ /\"\s*$/ ) { 316 $value =~ s/^\"//; 317 $value =~ s/\"\s*$//; 318 } elsif( $value =~ /^\[/ && $value =~ /\]\s*$/ ) { 319 $value = eval($value); 320 } elsif( $value =~ /^\{/ && $value =~ /\}\s*$/ ) { 321 $value = eval($value); 322 } 323 $cfg->{$key} = $value; 324 } 325} 326 327# no I18N::Japanese; for jperl 328BEGIN { 329 eval { require I18N::Japanese; }; 330 I18N::Japanese->unimport() unless($@); 331} 332 333# use bytes for Perl5.8 334BEGIN { 335 eval { require bytes; }; 336 bytes->import unless $@; 337} 338 339sub lastiskuten { 340 &lastiskuten_EUC; 341} 342 343sub lastiskuten_EUC { 344 my($str) = @_; 345 my @c = split('', $str); 346 my $lastiskuten = 0; 347 for( my $j = 0; $j <= $#c; $j++ ) { 348 my $c = $c[$j]; 349 $lastiskuten = 0; 350 if( $c eq "\x8e" ) { 351 $j++; 352 } elsif( $c eq "\x8f" ) { 353 $j += 2; 354 } elsif( $c lt "\xa0" ) { 355 } else { 356 my $k = $c.$c[$j+1]; 357 $j++; 358 $lastiskuten = 1 if grep {$_ eq $k} @KutenEUC; 359 } 360 } 361 $lastiskuten; 362} 363 364my %extin = ( 365"\xFA\xAF" => "\xED\x93", 366"\xFB\xE9" => "\xEE\xCD", 367"\xFA\xEC" => "\xED\xD0", 368"\xFB\x79" => "\xEE\x5D", 369"\xFA\xF2" => "\xED\xD6", 370"\xFA\xF3" => "\xED\xD7", 371"\xFA\x8F" => "\xED\x72", 372"\xFC\x4B" => "\xEE\xEC", 373"\xFB\x7C" => "\xEE\x60", 374"\xFA\xBD" => "\xED\xA1", 375"\xFA\xB4" => "\xED\x98", 376"\xFA\xB5" => "\xED\x99", 377"\xFC\x48" => "\xEE\xE9", 378"\xFB\x59" => "\xED\xFA", 379"\xFA\xE9" => "\xED\xCD", 380"\xFA\xFA" => "\xED\xDE", 381"\xFA\xBE" => "\xED\xA2", 382"\xFA\x81" => "\xED\x64", 383"\xFC\x47" => "\xEE\xE8", 384"\xFB\x73" => "\xEE\x57", 385"\xFB\x71" => "\xEE\x55", 386"\xFB\x72" => "\xEE\x56", 387"\xFA\xEE" => "\xED\xD2", 388"\xFB\x56" => "\xED\xF7", 389"\xFA\xF4" => "\xED\xD8", 390"\xFB\x57" => "\xED\xF8", 391"\xFB\x7A" => "\xEE\x5E", 392"\xFB\xA3" => "\xEE\x87", 393"\xFB\x5B" => "\xED\xFC", 394"\xFA\xB2" => "\xED\x96", 395"\xFA\xF0" => "\xED\xD4", 396"\xFA\x5D" => "\xED\x41", 397"\xFA\x6D" => "\xED\x51", 398"\xFB\x84" => "\xEE\x67", 399"\xFA\xB6" => "\xED\x9A", 400"\xFA\x69" => "\xED\x4D", 401"\xFB\x5C" => "\xEE\x40", 402"\xFB\xA6" => "\xEE\x8A", 403"\xFA\x8C" => "\xED\x6F", 404"\xFA\xF5" => "\xED\xD9", 405"\xFA\xF1" => "\xED\xD5", 406"\xFA\xAE" => "\xED\x92", 407"\xFB\xED" => "\xEE\xD1", 408"\xFA\x61" => "\xED\x45", 409"\xFB\x41" => "\xED\xE2", 410"\xFB\x55" => "\xED\xF6", 411"\xFA\xB0" => "\xED\x94", 412"\xFA\x73" => "\xED\x57", 413"\xFA\x85" => "\xED\x68", 414"\xFB\xEE" => "\xEE\xD2", 415"\xFB\x7B" => "\xEE\x5F", 416"\xFB\x5D" => "\xEE\x41", 417"\xFB\x65" => "\xEE\x49", 418"\xFB\x85" => "\xEE\x68", 419"\xFB\x51" => "\xED\xF2", 420"\xFB\xEF" => "\xEE\xD3", 421"\xFA\xC6" => "\xED\xAA", 422"\xFA\xF9" => "\xED\xDD", 423"\xFA\xB7" => "\xED\x9B", 424"\xFB\x87" => "\xEE\x6A", 425"\xFB\xA7" => "\xEE\x8B", 426"\xFA\xEB" => "\xED\xCF", 427"\xFA\x6A" => "\xED\x4E", 428"\xFB\xA4" => "\xEE\x88", 429"\xFA\x6E" => "\xED\x52", 430"\xFB\xF0" => "\xEE\xD4", 431"\xFB\xF1" => "\xEE\xD5", 432"\xFB\x93" => "\xEE\x76", 433"\xFA\xCE" => "\xED\xB2", 434"\xFB\xB8" => "\xEE\x9C", 435"\xFB\x60" => "\xEE\x44", 436"\xFA\xF6" => "\xED\xDA", 437"\xFA\xCC" => "\xED\xB0", 438"\xFB\x5A" => "\xED\xFB", 439"\xFA\xB3" => "\xED\x97", 440"\xFA\x8D" => "\xED\x70", 441"\xFA\xBA" => "\xED\x9E", 442"\xFA\x94" => "\xED\x77", 443"\xFA\xD1" => "\xED\xB5", 444"\xFB\xF2" => "\xEE\xD6", 445"\xFB\xE8" => "\xEE\xCC", 446"\xFB\xF3" => "\xEE\xD7", 447"\xFA\xB8" => "\xED\x9C", 448"\xFB\x42" => "\xED\xE3", 449"\xFB\x48" => "\xED\xE9", 450"\xFA\xC9" => "\xED\xAD", 451"\xFB\x61" => "\xEE\x45", 452"\xFA\x40" => "\xEE\xEF", 453"\xFA\x41" => "\xEE\xF0", 454"\xFB\xA2" => "\xEE\x86", 455"\xFA\x42" => "\xEE\xF1", 456"\xFB\x8D" => "\xEE\x70", 457"\xFA\x43" => "\xEE\xF2", 458"\xFB\x6E" => "\xEE\x52", 459"\xFA\x57" => "\xEE\xFC", 460"\xFA\x44" => "\xEE\xF3", 461"\xFA\x45" => "\xEE\xF4", 462"\xFA\x46" => "\xEE\xF5", 463"\xFA\x98" => "\xED\x7B", 464"\xFA\x47" => "\xEE\xF6", 465"\xFB\xC1" => "\xEE\xA5", 466"\xFA\x48" => "\xEE\xF7", 467"\xFA\xCF" => "\xED\xB3", 468"\xFA\x56" => "\xEE\xFB", 469"\xFA\x49" => "\xEE\xF8", 470"\xFB\xB9" => "\xEE\x9D", 471"\xFB\x67" => "\xEE\x4B", 472"\xFA\xF8" => "\xED\xDC", 473"\xFB\x69" => "\xEE\x4D", 474"\xFB\xF8" => "\xEE\xDC", 475"\xFB\xC3" => "\xEE\xA7", 476"\xFA\xDB" => "\xED\xBF", 477"\xFB\x68" => "\xEE\x4C", 478"\xFB\x64" => "\xEE\x48", 479"\xFB\x6A" => "\xEE\x4E", 480"\xFA\x92" => "\xED\x75", 481"\xFA\xD3" => "\xED\xB7", 482"\xFB\xA8" => "\xEE\x8C", 483"\xFB\x4A" => "\xED\xEB", 484"\xFB\x62" => "\xEE\x46", 485"\xFA\x67" => "\xED\x4B", 486"\xFA\x76" => "\xED\x5A", 487"\xFB\x46" => "\xED\xE7", 488"\xFB\xC2" => "\xEE\xA6", 489"\xFA\xCA" => "\xED\xAE", 490"\xFB\x49" => "\xED\xEA", 491"\xFB\xB6" => "\xEE\x9A", 492"\xFA\xD4" => "\xED\xB8", 493"\xFB\x8C" => "\xEE\x6F", 494"\xFA\x77" => "\xED\x5B", 495"\xFB\xF4" => "\xEE\xD8", 496"\xFB\x81" => "\xEE\x64", 497"\xFA\xDC" => "\xED\xC0", 498"\xFB\x63" => "\xEE\x47", 499"\xFA\xDF" => "\xED\xC3", 500"\xFB\xCC" => "\xEE\xB0", 501"\xFA\xD2" => "\xED\xB6", 502"\xFA\xBB" => "\xED\x9F", 503"\xFA\xCD" => "\xED\xB1", 504"\xFA\x91" => "\xED\x74", 505"\xFA\x9A" => "\xED\x7D", 506"\xFA\xF7" => "\xED\xDB", 507"\xFA\x99" => "\xED\x7C", 508"\xFA\x75" => "\xED\x59", 509"\xFB\x83" => "\xEE\x66", 510"\xFB\xEB" => "\xEE\xCF", 511"\xFB\xDE" => "\xEE\xC2", 512"\xFA\x63" => "\xED\x47", 513"\xFB\x44" => "\xED\xE5", 514"\xFB\x4C" => "\xED\xED", 515"\xFA\x70" => "\xED\x54", 516"\xFA\xDD" => "\xED\xC1", 517"\xFB\xAA" => "\xEE\x8E", 518"\xFB\xB5" => "\xEE\x99", 519"\xFA\xFC" => "\xED\xE0", 520"\xFB\x43" => "\xED\xE4", 521"\xFA\x95" => "\xED\x78", 522"\xFC\x46" => "\xEE\xE7", 523"\xFB\xF5" => "\xEE\xD9", 524"\xFB\xAF" => "\xEE\x93", 525"\xFA\x9F" => "\xED\x83", 526"\xFA\x9E" => "\xED\x82", 527"\xFA\xD0" => "\xED\xB4", 528"\xFB\xAB" => "\xEE\x8F", 529"\xFB\x45" => "\xED\xE6", 530"\xFA\xA8" => "\xED\x8C", 531"\xFB\xBB" => "\xEE\x9F", 532"\xFA\x6F" => "\xED\x53", 533"\xFB\x66" => "\xEE\x4A", 534"\xFB\x96" => "\xEE\x79", 535"\xFA\x72" => "\xED\x56", 536"\xFB\x8A" => "\xEE\x6D", 537"\xFA\xB9" => "\xED\x9D", 538"\xFB\xA5" => "\xEE\x89", 539"\xFC\x44" => "\xEE\xE5", 540"\xFB\xBA" => "\xEE\x9E", 541"\xFA\xE5" => "\xED\xC9", 542"\xFB\xFB" => "\xEE\xDF", 543"\xFB\xBC" => "\xEE\xA0", 544"\xFB\x47" => "\xED\xE8", 545"\xFA\x71" => "\xED\x55", 546"\xFB\x8E" => "\xEE\x71", 547"\xFB\xFC" => "\xEE\xE0", 548"\xFB\xCA" => "\xEE\xAE", 549"\xFB\x5F" => "\xEE\x43", 550"\xFA\x96" => "\xED\x79", 551"\xFC\x45" => "\xEE\xE6", 552"\xFB\xC4" => "\xEE\xA8", 553"\xFC\x40" => "\xEE\xE1", 554"\xFB\xE1" => "\xEE\xC5", 555"\xFB\xDD" => "\xEE\xC1", 556"\xFB\xC6" => "\xEE\xAA", 557"\xFB\xDB" => "\xEE\xBF", 558"\xFB\x99" => "\xEE\x7C", 559"\xFB\xBF" => "\xEE\xA3", 560"\xFA\xA4" => "\xED\x88", 561"\xFB\xC0" => "\xEE\xA4", 562"\xFB\x74" => "\xEE\x58", 563"\xFA\x74" => "\xED\x58", 564"\xFA\xFB" => "\xED\xDF", 565"\xFA\x7A" => "\xED\x5E", 566"\xFB\xD8" => "\xEE\xBC", 567"\xFB\xC5" => "\xEE\xA9", 568"\xFA\x78" => "\xED\x5C", 569"\xFB\x91" => "\xEE\x74", 570"\xFA\xE2" => "\xED\xC6", 571"\xFB\xD7" => "\xEE\xBB", 572"\xFB\xBD" => "\xEE\xA1", 573"\xFB\x6B" => "\xEE\x4F", 574"\xFB\x8B" => "\xEE\x6E", 575"\xFB\xBE" => "\xEE\xA2", 576"\xFA\x97" => "\xED\x7A", 577"\xFB\x88" => "\xEE\x6B", 578"\xFA\xD6" => "\xED\xBA", 579"\xFA\xD7" => "\xED\xBB", 580"\xFB\xD2" => "\xEE\xB6", 581"\xFA\xE4" => "\xED\xC8", 582"\xFA\x7D" => "\xED\x61", 583"\xFB\xD6" => "\xEE\xBA", 584"\xFB\xD4" => "\xEE\xB8", 585"\xFB\xC7" => "\xEE\xAB", 586"\xFB\xD0" => "\xEE\xB4", 587"\xFA\xCB" => "\xED\xAF", 588"\xFB\xD1" => "\xEE\xB5", 589"\xFB\x40" => "\xED\xE1", 590"\xFA\x84" => "\xED\x67", 591"\xFA\x82" => "\xED\x65", 592"\xFB\xC9" => "\xEE\xAD", 593"\xFA\xA5" => "\xED\x89", 594"\xFB\x94" => "\xEE\x77", 595"\xFB\xAC" => "\xEE\x90", 596"\xFA\xD5" => "\xED\xB9", 597"\xFB\x98" => "\xEE\x7B", 598"\xFB\xC8" => "\xEE\xAC", 599"\xFA\x86" => "\xED\x69", 600"\xFB\x9E" => "\xEE\x82", 601"\xFB\xD5" => "\xEE\xB9", 602"\xFB\x8F" => "\xEE\x72", 603"\xFA\x55" => "\xEE\xFA", 604"\xFB\xE2" => "\xEE\xC6", 605"\xFB\xCF" => "\xEE\xB3", 606"\xFB\x97" => "\xEE\x7A", 607"\xFA\x89" => "\xED\x6C", 608"\xFA\xC3" => "\xED\xA7", 609"\xFB\x4E" => "\xED\xEF", 610"\xFB\x4F" => "\xED\xF0", 611"\xFB\x77" => "\xEE\x5B", 612"\xFA\x8A" => "\xED\x6D", 613"\xFB\xAD" => "\xEE\x91", 614"\xFA\x60" => "\xED\x44", 615"\xFA\xDE" => "\xED\xC2", 616"\xFA\x66" => "\xED\x4A", 617"\xFB\xAE" => "\xEE\x92", 618"\xFA\xD9" => "\xED\xBD", 619"\xFB\x4D" => "\xED\xEE", 620"\xFB\xCB" => "\xEE\xAF", 621"\xFA\x5E" => "\xED\x42", 622"\xFA\x7E" => "\xED\x62", 623"\xFA\x90" => "\xED\x73", 624"\xFB\x6C" => "\xEE\x50", 625"\xFA\x9B" => "\xED\x7E", 626"\xFA\x7C" => "\xED\x60", 627"\xFA\x9C" => "\xED\x80", 628"\xFB\x6F" => "\xEE\x53", 629"\xFB\x90" => "\xEE\x73", 630"\xFB\x95" => "\xEE\x78", 631"\xFA\xC1" => "\xED\xA5", 632"\xFA\xB1" => "\xED\x95", 633"\xFA\x64" => "\xED\x48", 634"\xFA\xD8" => "\xED\xBC", 635"\xFA\x65" => "\xED\x49", 636"\xFA\xE8" => "\xED\xCC", 637"\xFA\x79" => "\xED\x5D", 638"\xFA\xEA" => "\xED\xCE", 639"\xFB\x58" => "\xED\xF9", 640"\xFB\x5E" => "\xEE\x42", 641"\xFB\x75" => "\xEE\x59", 642"\xFB\x7D" => "\xEE\x61", 643"\xFB\xE5" => "\xEE\xC9", 644"\xFB\x7E" => "\xEE\x62", 645"\xFB\xD9" => "\xEE\xBD", 646"\xFB\xE3" => "\xEE\xC7", 647"\xFA\xA0" => "\xED\x84", 648"\xFA\xE6" => "\xED\xCA", 649"\xFB\xDC" => "\xEE\xC0", 650"\xFA\xE7" => "\xED\xCB", 651"\xFB\xE0" => "\xEE\xC4", 652"\xFB\xCD" => "\xEE\xB1", 653"\xFA\xE1" => "\xED\xC5", 654"\xFB\x80" => "\xEE\x63", 655"\xFB\xCE" => "\xEE\xB2", 656"\xFA\x87" => "\xED\x6A", 657"\xFB\x82" => "\xEE\x65", 658"\xFB\x86" => "\xEE\x69", 659"\xFB\x89" => "\xEE\x6C", 660"\xFB\x92" => "\xEE\x75", 661"\xFB\x9D" => "\xEE\x81", 662"\xFA\xC0" => "\xED\xA4", 663"\xFC\x42" => "\xEE\xE3", 664"\xFA\xA1" => "\xED\x85", 665"\xFB\xB2" => "\xEE\x96", 666"\xFC\x41" => "\xEE\xE2", 667"\xFA\xA2" => "\xED\x86", 668"\xFC\x4A" => "\xEE\xEB", 669"\xFB\x9F" => "\xEE\x83", 670"\xFB\xA0" => "\xEE\x84", 671"\xFA\xC5" => "\xED\xA9", 672"\xFA\xA7" => "\xED\x8B", 673"\xFA\xE0" => "\xED\xC4", 674"\xFB\x52" => "\xED\xF3", 675"\xFB\x6D" => "\xEE\x51", 676"\xFB\xA9" => "\xEE\x8D", 677"\xFB\xB1" => "\xEE\x95", 678"\xFA\xC7" => "\xED\xAB", 679"\xFB\x4B" => "\xED\xEC", 680"\xFB\x54" => "\xED\xF5", 681"\xFB\xB3" => "\xEE\x97", 682"\xFB\xB4" => "\xEE\x98", 683"\xFA\xAB" => "\xED\x8F", 684"\xFA\x8B" => "\xED\x6E", 685"\xFA\x83" => "\xED\x66", 686"\xFB\xB7" => "\xEE\x9B", 687"\xFA\xBF" => "\xED\xA3", 688"\xFA\xAC" => "\xED\x90", 689"\xFB\xFA" => "\xEE\xDE", 690"\xFB\xD3" => "\xEE\xB7", 691"\xFA\x80" => "\xED\x63", 692"\xFB\xDA" => "\xEE\xBE", 693"\xFA\xC4" => "\xED\xA8", 694"\xFB\x50" => "\xED\xF1", 695"\xFB\xEA" => "\xEE\xCE", 696"\xFB\x78" => "\xEE\x5C", 697"\xFA\xE3" => "\xED\xC7", 698"\xFB\x9A" => "\xEE\x7D", 699"\xFB\xE6" => "\xEE\xCA", 700"\xFA\xA3" => "\xED\x87", 701"\xFB\x76" => "\xEE\x5A", 702"\xFB\xE7" => "\xEE\xCB", 703"\xFB\xF6" => "\xEE\xDA", 704"\xFA\xED" => "\xED\xD1", 705"\xFB\xF7" => "\xEE\xDB", 706"\xFA\x5F" => "\xED\x43", 707"\xFB\x9B" => "\xEE\x7E", 708"\xFB\xF9" => "\xEE\xDD", 709"\xFA\x8E" => "\xED\x71", 710"\xFC\x49" => "\xEE\xEA", 711"\xFA\xDA" => "\xED\xBE", 712"\xFB\x53" => "\xED\xF4", 713"\xFA\xC8" => "\xED\xAC", 714"\xFA\xBC" => "\xED\xA0", 715"\xFB\xB0" => "\xEE\x94", 716"\xFB\xE4" => "\xEE\xC8", 717"\xFA\x62" => "\xED\x46", 718"\xFA\x88" => "\xED\x6B", 719"\xFA\x7B" => "\xED\x5F", 720"\xFB\xDF" => "\xEE\xC3", 721"\xFA\xA9" => "\xED\x8D", 722"\xFA\x5C" => "\xED\x40", 723"\xFB\xA1" => "\xEE\x85", 724"\xFC\x43" => "\xEE\xE4", 725"\xFA\x6B" => "\xED\x4F", 726"\xFA\xAD" => "\xED\x91", 727"\xFA\x6C" => "\xED\x50", 728"\xFA\xC2" => "\xED\xA6", 729"\xFA\xEF" => "\xED\xD3", 730"\xFA\xA6" => "\xED\x8A", 731"\xFA\x68" => "\xED\x4C", 732"\xFA\x93" => "\xED\x76", 733"\xFB\x9C" => "\xEE\x80", 734"\xFA\x9D" => "\xED\x81", 735"\xFB\xEC" => "\xEE\xD0", 736"\xFB\x70" => "\xEE\x54", 737"\xFA\xAA" => "\xED\x8E", 738); 739 740sub _sjis2euc { 741 my($c1,$c2) = @_; 742 743 $c1 = ord($c1); 744 $c2 = ord($c2); 745 chr((($c1 - ($c1 < 160 ? 112 : 176)) << 1) - ($c2 < 159) + 128) 746 . chr($c2 - (($c2 < 159) ? ($c2 > 127 ? 32 : 31) : 126) + 128); 747} 748 749sub sjis2euc { 750 my($string) = @_; 751 my ($j,$c,$c2,@c); 752 my $ctype = '1'; # 1:ASCII K:���p�J�i 2:2�o�C�g���� 753 my $result; 754 755 @c = split(//,$string); 756 for( $j = 0; $j <= $#c; $j++ ) { 757 $c = $c[$j]; 758 if( $c =~ /[\x00-\x7f]/ ) { 759 $result .= $c; 760 } elsif( $c =~ /[\x81-\x9f\xe0-\xef]/ ) { 761 last if( ++$j > $#c ); $c2 = $c[$j]; 762 if( $c2 =~ /[\x40-\xfc]/ ) { 763 $result .= _sjis2euc($c,$c2); 764 } else { 765 $result .= $c . $c2; 766 } 767 } elsif( $c ge "\xfa" ) { 768 last if( ++$j > $#c ); $c2 = $c[$j]; 769 if( $extin{$c.$c2} ) { 770 $result .= _sjis2euc(split(//, $extin{$c.$c2})); 771 } else { 772 $result .= "\xa2\xa3"; 773 } 774 } elsif( $c =~ /[\xa1-\xdf]/ ) { 775 $result .= "\x8e" . $c; 776 } else { 777 $result .= $c; 778 } 779 } 780 $result; 781} 782