tanihito’s blog

デジタル・新規事業開発・健康など、興味のあることについてつらつらと書いてきます。

Wordの文献リストをBibTeXに変換する

最近WordからTeXに乗り換えました。図の位置とかを気にしなくていいので楽ですね。今までWordで作ってきた文献リストをTeXでも使いたいので、Wordの文献リスト(マスタリスト)をBibTeXに変換するスクリプトを書きました。

Wordの文献リストは"C:\Documents and Settings\\Application Data\Microsoft\Bibliography\Sources.xml"に保存されているので、word2bibtex.pyと同じディレクトリにコピーします。あとはスクリプトを実行するだけでBibTeXファイルSources.bibが出力されます。

$ python word2bibtex.py


word2bibtex.py

# -*- coding: utf-8 -*-
import sys
from BeautifulSoup import BeautifulSoup

def word2bib(xmlname, bibname):
    """
    Wordのマスタリストをbibファイルに変換
    """    
    articles = read_sourcexml(xmlname)
    write_bib(articles, bibname)
    
def read_sourcexml(xmlname):
    """
    Wordのマスタリストを読み込む
    """
    encoding = 'utf-8'
    articles = []
    with open(xmlname, "r") as sourcexml:
        xml = sourcexml.read()
        soup = BeautifulSoup(xml)
        sources = soup.findAll("b:source")
        for source in sources:
            try:
                article = {}
                persons = []
                namelist = source.find("b:namelist")
                for i, person in enumerate(namelist.contents):
                    firstname = person.find("b:first").string.encode(encoding)
                    lastname  = person.find("b:last").string.encode(encoding)
                    persons.append(firstname + " " + lastname)                        
                article["author"]     = " and ".join(persons)
                article["title"]      = source.find("b:title").string.encode(encoding)
                article["booktitle"]  = source.find("b:institution").string.encode(encoding)
                article["year"]       = source.find("b:year").string.encode(encoding)
                articles.append(article)
            except Exception as e:
                print e
                sys.stderr.write(str(source)+ "\n")
    return articles

def write_bib(articles, bibname):
    """
    bibファイルを書き込む
    """
    with open(bibname, "w") as bib:
        for article in articles:
            tag = make_tag(article)
            bib.write("@InProceedings{%s,\n" % tag)
            for k,v in article.items():
                bib.write("%s = {%s},\n" % (k,v))
            bib.write("}\n\n")

def make_tag(article):
    """
    tag ::= <著者名字> <発行年の下2桁> ':' <タイトルの最初の単語>
    """
    tag  = ""
    tag += article["author"].split(" ")[1].lower()
    tag += article["year"][-2:]
    tag += ":"
    tag += article["title"].split(" ")[0].lower()
    return tag
    
if __name__ == "__main__":
    xmlname = "Sources.xml"
    bibname = "Sources.bib"
    word2bib(xmlname, bibname)