引用の書き方とPythonコードによる自動変換

Python

はじめに

サイトとか社内技術文書とかを書いていると、学術論文等の引用を行いたい場面が出てくると思う。
一方、Zotaroなどのフリーソフトをダウンロードしずらいといった場面が出てくると思う。
そこで、今回は手動でのやり方とPythonコードによる自動変換のやり方を紹介します。
またほかにも似たような記事(wordpressにおける論文引用の仕方 – たこやきたべたい)を書いています。

引用ルール

まず初めに引用スタイルは各ジャーナルによって異なる
自分はなんとなくnature styleが気に入って使っているのでこちらでやっていきます。

nature styleの手動書き換えと基本スタイル理解

まず初めに、基本的に今回紹介するのは以下のサイトを日本語に訳したものになります。
Nature citation style [Update January 2025] – Paperpile
英語を読める方は上記のサイトで直接見たほうが確実です。

学術雑誌論文

著者1名の雑誌論文

1. Herrmann, M. Plasma physics: A promising advance in nuclear fusion. Nature 506, 302–303 (2014).

著者2名の雑誌論文

1. Moar, W. J. & Anilkumar, K. J. Plant science. The power of the pyramid. Science 318, 1561–1562 (2007).

著者3名の雑誌論文

1. Bandyopadhyay, P. R., Leinhos, H. A. & Hellum, A. M. Handedness helps homing in swimming and flying animals. Sci. Rep. 3, 1128 (2013).

著者6名以上の雑誌論文

1. Celikel, R. et al. Modulation of alpha-thrombin function by distinct interactions with platelet glycoprotein Ibalpha. Science 301, 218–221 (2003).

教科書や教科書の章

通常の教科書

1. Benitez, M., Davidson, J. & Flaxman, L. Small Schools, Big Ideas. (Jossey-Bass, San Francisco, CA, USA, 2009).

編纂本

1. Neutron Applications in Materials for Energy. (Springer International Publishing, Cham, 2015).

編纂された本の中の一部の章

1. Sheehan, W. & Conselice, C. J. Of Leviathans, Spirals, and Fire-Mists. in Galactic Encounters: Our Majestic and Evolving Star-System, From the Big Bang to Time’s End (ed. Conselice, C. J.) 79–98 (Springer, New York, NY, 2015).

ウェブサイト

ウェブサイトへの参照は、参考文献リストではなく、本文に直接表示される場合があります。ネイチャーの著者への指示を参照してください。

ブログ投稿

1. Andrew, E. Hungry Snake Picked The Wrong Dinner. IFLScience https://www.iflscience.com/plants-and-animals/hungry-snake-picked-wrong-dinner/ (2014).

レポート

この例は、政府報告書、技術報告書、および科学報告書に使用される一般的な構造を示しています。レポート番号が見つからない場合は、レポートを書籍として引用する方が良い場合があります。レポートでは、通常、「米国食品医薬品局」や「国立がん研究所」などの政府機関や機関が著者としてクレジットされ、個人がクレジットされることはありません。

政府報告書

1. Government Accountability Office. Social Security: Quality of Services Generally Rated High by Clients Sampled.(1986).

新聞記事

学術雑誌とは異なり、新聞には通常、巻や号の番号はありません。代わりに、正しい参照のために完全な日付とページ番号が必要です。

ニューヨークタイムズの記事

1. Saslow, L. Putting the Pan in Pan-American. New York Times 14LI8 (2006).

論文および学位論文

博士論文、修士論文、学士論文を含む論文は、以下に概説する基本形式に従います。
博士論文

1. Glasgow, H. L. Design and Selection of Probes for In Vivo Molecular Targeting and Imaging. (University of California San Diego, La Jolla, CA, 2015).

引用の仕方

one reference 1.
two references 1,2.
four references 1–4.

Pythonコード

コードの可読性を上げるために一部chatGPの力を借りたが以下の様にコードがかけます。
自分でもまだ使い倒していないので、もし間違い等あればご連絡ください。

import re

def format_nature_citation(bibtex_entry):
    """
    BibTeX形式の文献情報をNatureの引用スタイルに変換します。

    Args:
        bibtex_entry (str): BibTeX形式の文献情報。

    Returns:
        str: Natureスタイルに整形された引用文献。
             必要な情報が不足している場合はエラーメッセージを返します。
    """
    entry_type_match = re.search(r'@(\w+){', bibtex_entry)
    if not entry_type_match:
        return "エラー:文献タイプを特定できません。"
    entry_type = entry_type_match.group(1).lower()

    fields = {}
    for match in re.finditer(r'(\w+)\s*=\s*{(.*?)}', bibtex_entry):
        key = match.group(1).lower()
        value = match.group(2).strip()
        fields[key] = value

    if entry_type == 'article':
        required_fields = ['author', 'title', 'journal', 'volume', 'pages', 'year']
        if not all(field in fields for field in required_fields):
            return "エラー:論文に必要な情報が不足しています。"

        authors = fields['author'].replace(' and ', ', ').split(', ')
        formatted_authors = []
        for author in authors:
            parts = author.split(', ')
            if len(parts) == 2:
                last_name = parts[0]
                first_name = parts[1]
                initials = "".join([name[0] + "." for name in first_name.split()])
                formatted_authors.append(f"{last_name} {initials}")
            else:
                # 著者名の形式が想定外の場合
                formatted_authors.append(author) # そのまま表示

        if len(formatted_authors) > 1:
            formatted_authors_str = ", ".join(formatted_authors[:-1]) + " & " + formatted_authors[-1]
            if len(formatted_authors) >= 6:
                formatted_authors_str = formatted_authors[0] + "* et al. *"
        else:
            formatted_authors_str = formatted_authors[0]

        title = fields['title'].strip().rstrip('.')
        journal = fields['journal'].strip()
        volume = fields['volume'].strip()
        pages = fields['pages'].strip()
        year = fields['year'].strip()

        return f"{formatted_authors_str}. {title}. *{journal}* **{volume}**, {pages} ({year})."

    elif entry_type == 'book':
        required_fields = ['author', 'title', 'publisher', 'year']
        if not all(field in fields for field in required_fields):
            return "エラー:書籍に必要な情報が不足しています。"

        authors = fields['author'].replace(' and ', ', ').split(', ')
        formatted_authors = []
        for author in authors:
            parts = author.split(', ')
            if len(parts) == 2:
                last_name = parts[0]
                first_name = parts[1]
                initials = "".join([name[0] + "." for name in first_name.split()])
                formatted_authors.append(f"{last_name} {initials}")
            else:
                formatted_authors.append(author)

        if len(formatted_authors) > 1:
            formatted_authors_str = ", ".join(formatted_authors[:-1]) + " & " + formatted_authors[-1]
            if len(formatted_authors) >= 6:
                formatted_authors_str = formatted_authors[0] + "* et al. *"
        
        else:
            formatted_authors_str = formatted_authors[0]

        title = fields['title'].strip().rstrip('.')
        publisher = fields['publisher'].strip()
        year = fields['year'].strip()

        # Place of Publicationの情報があれば追加 (BibTeXの標準フィールドではない場合があるので注意)
        place = fields.get('address', '')
        if place:
            return f"{formatted_authors_str}. *{title}*. {publisher}, {place}, {year}."
        else:
            return f"{formatted_authors_str}. *{title}*. {publisher}, {year}."

    elif entry_type == 'online' or entry_type == 'misc' or 'webpage' in entry_type:
        required_fields = ['author', 'title', 'url', 'year']
        if not all(field in fields for field in required_fields):
            return "エラー:ウェブサイトに必要な情報が不足しています。"

        authors = fields['author'].replace(' and ', ', ').split(', ')
        formatted_authors = []
        for author in authors:
            parts = author.split(', ')
            if len(parts) == 2:
                last_name = parts[0]
                first_name = parts[1]
                initials = "".join([name[0] + "." for name in first_name.split()])
                formatted_authors.append(f"{last_name} {initials}")
            else:
                formatted_authors.append(author)

        if len(formatted_authors) > 1:
            formatted_authors_str = ", ".join(formatted_authors[:-1]) + " & " + formatted_authors[-1]
        else:
            formatted_authors_str = formatted_authors[0]

        title = fields['title'].strip().rstrip('.')
        url = fields['url'].strip()
        year = fields['year'].strip()
        # Accessed date は BibTeX に標準ではないため、必要であれば別途処理を追加
        return f"{formatted_authors_str}. {title}. {url} ({year})."

    else:
        return f"エラー:サポートされていない文献タイプです: {entry_type}"

コメント

タイトルとURLをコピーしました