.

...back to the entrance

● CSVファイルからBIBファイルをつくる 2003-08-06 [4th]
LaTeXとBibTeXを組み合わせると、文献データベースから半自動的に参考文献リストや引用注を作成することができるし、データベースが一つあれば、論文を何本書こうといつでも同じデータベースからそれぞれの論文で使用した文献リストを得ることができるので、とてつもなく便利です。やや面倒なのはデータベースファイル(BIBファイル)を所定の書式で書かねばならないという点。そこで、文献データの管理は見通しのよいCSVで行い、BIBファイルをそこからエクスポートするというのがここでの目的です。もっとエレガントな方法があったら教えてください。

使用するCSVエディタはなんでもかまいません。ちなみに私はListPadです。
1行目は見出し行になります。私の場合、「entry」「ID」「author」「title」「editor」「booktitle」「publisher」「journal」「volume」「number」「pages」「year」「yomi」「note」の14見出しです。 利用する entry の種類は @book, @incollection, @article の3種類です。これらに共通する必須入力項目は「entry」「ID」のほかに「author」「title」「year」、加えて「yomi」も個人的に必ず入れています。

CSVにはいくつかの形式がありますが、以下のものが標準だそうです(エクセルもこの形式で出力するとのこと)。
  1. 行内の各項目はカンマで区切る。
  2. 行はCR+LF(リターン)で区切る。
  3. 文字列項目は「"」で括る。
  4. 項目内で「"」が使われる場合は「""」と置換する。
  5. 数値項目は半角、3桁区切り無し、「"」括り無しで保存する。
以下のPerlスクリプトは、CSVファイルの各行から値(項目)を取り出し(工程1)、キーと対応するデータの組をつくり(工程2)、それをBIBファイル(ref.bib)に書き込む(工程3)ものです。 青色の部分が工程1です。大橋博基氏のスクリプトを利用させていただきました。そのおかげで以前の自作スクリプトより圧倒的に高速です。
なお、緑色の部分は文字列中のダブルクォートをLaTeXの書式に変換するために、この部分だけ元のスクリプトを書き換えてあります。
# ―――――――――――――――――――――――――――――――
#                 ref.pl  ( xxx.csv -> ref.bib )
# ―――――――――――――――――――――――――――――─―
rename("ref.bib", "ref.old");                # バックアップする
open(BIB, "> ref.bib");
$line = <>;                                  # 1行目を読み捨てる
while($line = <>) {                          # 値のリストを抽出
    $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;
    @values = map {/^"(.*)"$/ ?
        scalar($_ = $1, s/""([^"]+)""/``\1''/g, $_) : $_}
        ($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
    %forbib = (                              # キーとデータの組
        "author" => $values[2],
        "title" => $values[3],
        "editor" => $values[4],
        "booktitle" => $values[5],
        "publisher" => $values[6],
        "journal" => $values[7],
        "volume" => $values[8],
        "number" => $values[9],
        "pages" => $values[10],
        "year" => $values[11],
        "yomi" => $values[12],
        "note" => $values[13]
    );
    print BIB "\@$values[0]\{$values[1],\n"; # ファイルに書き込む
    while (($key, $data) = each(%forbib)) {
        if($data) {
            print BIB "\t$key = \"$data\",\n";
        }
    }
    print BIB "\}\n";
}
close(BIB);

...to the top