|
本帖最后由 wingdd 于 2024-5-30 16:51 编辑
青苹果数据中心出版的
家庭藏书集锦 家庭生活与艺术
家庭藏书集锦 法律经济军事
家庭藏书集锦 哲学
二十五史全集CD1
二十五史全集CD2
家庭藏书集锦 历史
家庭藏书集锦 马恩列全集
家庭藏书集锦 百科全书
上面的光盘的pdf在adobe reader 福晰阅读器下书签显示乱码,需要修正书签
UnicornViewer可以正常浏览,但是PdgCntEditor编辑书签有时会出现乱码.
回归问题的本质,早期青苹果数据中心出版的这些电子图书pdf内部书签文本编码不规范
这些pdf的书签使用不规范的Unicode编码字符串,gbk编码字符和8进制转义字符,甚至在这些文本中还有针对于换行符回车符的转义字符
既然问题清楚了,只需要修改对应的书签文本,使之符合pdf的标准,就能让这些pdf在阅读器下正常工作.
执行命令
修复效果
测试了1000多个pdf未发现异常.
代码
- use feature 'say';
- use strict;
- use warnings;
- use utf8;
- use open IN => ':raw', OUT => ':raw';
- use Encode ( 'decode', 'encode' );
- my ( $filename_in, $filename_out ) = @ARGV;
- if ( ( not defined $filename_in ) || ( not defined $filename_out ) ) {
- die "perl 修复早期青苹果pdf书签.pl <input.pdf> <out.pdf>\n";
- }
- open my $fh1, "<", $filename_in or die $!;
- my $pdf_bin = do { local $/; <$fh1>; };
- close $fh1;
- sub deal_with_obj {
- my $obj = $_[0];
- if ( ( $obj =~ m/\/Title \(([^\n]+)\)/s ) && ( $obj =~ m/\/First |\/Parent / ) ) {
- $obj =~ m/\/Title \(([^\n]+)\)/s;
- my $title = $1;
- $title =~ s/\r|\n//g;
- if ( $title =~ m/\A\x{ff}\x{fe}/ ) {
- #say 'fffe';
- $title =~ s/\A\x{ff}\x{fe}//;
- $title =~ s/\\n/\n/g;
- $title =~ s/\\r/\r/g;
- $title =~ s/\\t/\t/g;
- $title =~ s/\\(.)/$1/g;
- my $out_str_escaped = "<" . "feff" . unpack( 'H*', $title ) . ">";
- $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
- }
- elsif ( $title =~ m/\A\x{fe}\x{ff}/ ) {
- #say 'feff';
- $title =~ s/\A\x{fe}\x{ff}//;
- $title =~ s/\\n/\n/g;
- $title =~ s/\\r/\r/g;
- $title =~ s/\\t/\t/g;
- $title =~ s/\\(.)/$1/g;
- my $out_str_escaped = "<" . "feff" . unpack( 'H*', $title ) . ">";
- $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
- }
- elsif ( $title =~ m/\\\d{3}/ ) {
- #say '\\000';
- my $out_str = "";
- $title =~ s/\\n/\\014/g;
- $title =~ s/\\r/\\015/g;
- $title =~ s/\\t/\\011/g;
- while ( $title =~ m/(\\\d{3}|[ -'\*-\/:-\[\]-~0-9])/g ) {
- my $chars = $1;
- if ( $chars =~ m/\\\d{3}/ ) {
- my $chars_new = $chars;
- $chars_new =~ s/\\//;
- my $str = pack( 'H*', sprintf( "%02x", oct( '0' . $chars_new ) ) );
- $out_str = $out_str . $str;
- }
- else {
- $out_str = $out_str . $chars;
- }
- }
- if ( $out_str =~ m/\A\x{ff}\x{fe}/ ) {
- $out_str =~ s/\x{ff}\x{fe}//;
- }
- else {
- $out_str = encode( 'UTF-16BE', decode( 'gbk', $out_str ) );
- }
- my $out_str_escaped = "<" . "feff" . unpack( 'H*', $out_str ) . ">";
- $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
- }
- else {
- #say 'gbk';
- $title =~ s/\\n/\n/g;
- $title =~ s/\\r/\r/g;
- $title =~ s/\\t/\t/g;
- $title =~ s/\\(.)/$1/g;
- my $out_str_encode = encode( 'UTF-16BE', decode( 'gbk', $title ) );
- my $out_str_escaped = "<" . "feff" . unpack( 'H*', $out_str_encode ) . ">";
- $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
- }
- }
- return $obj;
- }
- $pdf_bin =~ s/(\d+ \d+ obj(\r|\n|\r\n).+?(\r|\n|\r\n)endobj(\r|\n|\r\n))/deal_with_obj($1)/esg;
- open my $fh2, ">", $filename_out or die $!;
- print $fh2 $pdf_bin;
- close $fh2;
复制代码 感觉有用的朋友可以下载附件支持一下.
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
评分
-
3
查看全部评分
-
|