PDF metadata viewer/writer (PDFメタデータの表示・書き込み perlスクリプト)


戻る一つ前のメニューに戻る

Linuxには手軽にpdfメタデータを変更するソフトがないため、スクリプトを作成する必要がある。(Windowsであれば、無償公開されているPDF Exchange Viewerなどを利用すれば簡単に書き換えられる)

スクリプトの使用方法例

メタデータを書き換える例。書き換え文字列に「@」を指定すると、空白値に変換される。

# pdf-metadata$ perl pdf-metadata.pl ../book.pdf -author="ミルトン フリードマン" -title="資本主義と自由" -creater="Image Scanner" -producer=@ -subject="新自由主義のマクロ経済学書籍" -keywords="経済学 マクロ経済 自由主義"

メタデータを表示する例(pdfinfoコマンドの出力形式と同じような形になる)

# perl pdf-metadata.pl ../book.pdf -lCurrent metadata listing...
Title:資本主義と自由
Author:ミルトン フリードマン
Creator:Image Scanner
Producer:NONE
Subject:新自由主義のマクロ経済学書籍
Keywords:経済学 マクロ経済 自由主義

PDFメタデータの表示・書き込みを行うperlスクリプト

スクリプトは、文字エンコードをutf8で保存してください。

#!/usr/bin/perl
 
# GNU GPL Free Software. (C) 2011 INOUE Hirokazu
# PDFファイルのメタデータを表示、書き換えするスクリプト
 
use strict;
use warnings;
use utf8;
 
use PDF::API2;
use PDF::API2::Page;
use Getopt::Long;
use File::Basename;
use Encode::Guess qw/euc-jp shiftjis iso-2022-jp/;
 
my $flag_os = 'linux';  # linux/windows
my $flag_charcode = 'utf8';             # utf8/shiftjis
 
# IOの文字コードを規定
if($flag_charcode eq 'utf8'){
        binmode(STDIN, ":utf8");
        binmode(STDOUT, ":utf8");
        binmode(STDERR, ":utf8");
}
if($flag_charcode eq 'shiftjis'){
        binmode(STDIN, "encoding(sjis)");
        binmode(STDOUT, "encoding(sjis)");
        binmode(STDERR, "encoding(sjis)");
}
 
 
my $flag_list_only = 0;
my $str_new_author;
my $str_new_title;
my $str_new_creater;
my $str_new_producer;
my $str_new_subject;
my $str_new_keywords;
 
 
GetOptions('list|l' => \ $flag_list_only,
        'author=s' => \ $str_new_author,
        'title=s' => \ $str_new_title,
        'creater=s' => \ $str_new_creater,
        'producer=s' => \ $str_new_producer,
        'subject=s' => \ $str_new_subject,
        'keywords=s' => \ $str_new_keywords);
 
if($#ARGV != 0){ sub_print_usage(); exit; }
my $pdf_filename = $ARGV[0];
if( ! -f $pdf_filename ){ die("input pdf file not found\n"); }
 
 
my $pdf = PDF::API2->open($pdf_filename);
my %metadata = $pdf->info();
 
print("Current metadata listing...\n");
if(defined($metadata{'Title'})){ print("Title:".$metadata{'Title'}."\n"); }
if(defined($metadata{'Author'})){ print("Author:".$metadata{'Author'}."\n"); }
if(defined($metadata{'Creator'})){ print("Creator:".$metadata{'Creator'}."\n"); }
if(defined($metadata{'Producer'})){ print("Producer:".$metadata{'Producer'}."\n"); }
if(defined($metadata{'Subject'})){ print("Subject:".$metadata{'Subject'}."\n"); }
if(defined($metadata{'Keywords'})){ print("Keywords:".$metadata{'Keywords'}."\n"); }
 
if($flag_list_only){ exit; }
 
print("\nChange metadata with following data...\n");
if(defined($str_new_title)){
    $str_new_title = sub_conv_to_flagged_utf8($str_new_title);
    if($str_new_title eq '@'){ $str_new_title = ''; }
    print("New Title:".$str_new_title."\n");
    $metadata{'Title'} = $str_new_title;
}
if(defined($str_new_author)){
    $str_new_author = sub_conv_to_flagged_utf8($str_new_author);
    if($str_new_author eq '@'){ $str_new_author = ''; }
    print("New Author:".$str_new_author."\n");
    $metadata{'Author'} = $str_new_author;
}
if(defined($str_new_creater)){
    $str_new_creater = sub_conv_to_flagged_utf8($str_new_creater);
    if($str_new_creater eq '@'){ $str_new_creater = ''; }
    print("New Creator:".$str_new_creater."\n");
    $metadata{'Creator'} = $str_new_creater;
}
if(defined($str_new_producer)){
    $str_new_producer = sub_conv_to_flagged_utf8($str_new_producer);
    if($str_new_producer eq '@'){ $str_new_producer = ''; }
    print("New Producer:".$str_new_producer."\n");
    $metadata{'Producer'} = $str_new_producer;
}
if(defined($str_new_subject)){
    $str_new_subject = sub_conv_to_flagged_utf8($str_new_subject);
    if($str_new_subject eq '@'){ $str_new_subject = ''; }
    print("New Subject:".$str_new_subject."\n");
    $metadata{'Subject'} = $str_new_subject;
}
if(defined($str_new_keywords)){
    $str_new_keywords = sub_conv_to_flagged_utf8($str_new_keywords);
    if($str_new_keywords eq '@'){ $str_new_keywords = ''; }
    print("New Keywords:".$str_new_keywords."\n");
    $metadata{'Keywords'} = $str_new_keywords;
}
 
$pdf->info(%metadata);
$pdf->saveas($pdf_filename);
 
print("\nMetadata changed\n");
 
 
# 任意の文字コードの文字列を、UTF-8フラグ付きのUTF-8に変換する
sub sub_conv_to_flagged_utf8{
        my $str = shift;
        my $enc_force = undef;
        if(@_ >= 1){ $enc_force = shift; }              # デコーダの強制指定
 
        # デコーダが強制的に指定された場合
        if(defined($enc_force)){
                if(ref($enc_force)){
                        $str = $enc_force->decode($str);
                        return($str);
                }
                elsif($enc_force ne '')
                {
                        $str = Encode::decode($enc_force, $str);
                }
        }
 
        my $enc = Encode::Guess->guess($str);   # 文字列のエンコードの判定
 
        unless(ref($enc)){
                # エンコード形式が2個以上帰ってきた場合 (shiftjis or utf8)
                my @arr_encodes = split(/ /, $enc);
                if(grep(/^$flag_charcode/, @arr_encodes) >= 1){
                        # $flag_charcode と同じエンコードが検出されたら、それを優先する
                        $str = Encode::decode($flag_charcode, $str);
                }
                elsif(lc($arr_encodes[0]) eq 'shiftjis' || lc($arr_encodes[0]) eq 'euc-jp' || 
                        lc($arr_encodes[0]) eq 'utf8' || lc($arr_encodes[0]) eq 'us-ascii'){
                        # 最初の候補でデコードする
                        $str = Encode::decode($arr_encodes[0], $str);
                }
        }
        else{
                # UTF-8でUTF-8フラグが立っている時以外は、変換を行う
                unless(ref($enc) eq 'Encode::utf8' && utf8::is_utf8($str) == 1){
                        $str = $enc->decode($str);
                }
        }
 
        return($str);
}
 
 
# 任意の文字コードの文字列を、UTF-8フラグ無しのUTF-8に変換する
sub sub_conv_to_unflagged_utf8{
        my $str = shift;
 
        # いったん、フラグ付きのUTF-8に変換
        $str = sub_conv_to_flagged_utf8($str);
 
        return(Encode::encode('utf8', $str));
}
 
 
# UTF8から現在のOSの文字コードに変換する
sub sub_conv_to_local_charset{
        my $str = shift;
 
        # UTF8から、指定された(OSの)文字コードに変換する
        $str = Encode::encode($flag_charcode, $str);
 
        return($str);
}
 
# ヘルプを表示する
sub sub_print_usage {
    print("NAME\n".
            "    ".basename($0, '.pl')." - pdf metadata viewer/writer\n\n".
            "SYNOPSIS\n".
            "   ".basename($0)." [options] [PDF file]\n\n".
            "OPTIONS\n".
            "    -l, -list\n".
            "        view metadata\n".
            "    -title=str\n".
            "        change title to 'str'\n".
            "    -author=str\n".
            "        change author to 'str'\n".
            "    -creater=str\n".
            "        change creater to 'str'\n".
            "    -producer=str\n".
            "        change producer to 'str'\n".
            "    -subject=str\n".
            "        change subject to 'str'\n".
            "    -keywords=str\n".
            "        change keywords to 'str'\n\n".
            "EXAMPLES\n".
            "    ".basename($0)." test.pdf -title=Mathematica -keywords=\'mathematics science\'\n\n".
            "    ".basename($0)." test.pdf -title=\"Capitalism and Freedom\"\n\n".
            "SEE ALSO\n".
            "    pdfinfo, identify\n\n"
            );
}

参考資料

戻る一つ前のメニューに戻る