Python Citeproc: Fehler bei aktualisierter apa.csl, funktioniert einwandfrei mit alter apa.csl
Posted: 03 Jan 2025, 14:11
Ich verwende die Bibliothek „citeproc-py“, um Zitate im APA-Stil in Python zu generieren. Es funktioniert perfekt mit einer älteren Version von apa.csl, aber wenn ich zur aktualisierten Version (heruntergeladen aus dem CSL-GitHub-Repository) wechsle, zeigt Old CSL
Wie man dieses Problem löst.
Was ich versucht habe:
Testen der alten apa.csl: Das funktioniert perfekt und ohne Fehler.
Wie man dieses Problem löst.
Was ich versucht habe:
Testen der alten apa.csl: Das funktioniert perfekt und ohne Fehler.
Code: Select all
import requests
import json
from pybtex.database import parse_string
from citeproc import CitationStylesStyle, CitationStylesBibliography
from citeproc import Citation, CitationItem
from citeproc import formatter
from citeproc.source.json import CiteProcJSON
# Function to fetch metadata using DOI from CrossRef in BibTeX format
def fetch_metadata_from_doi(doi):
url = f"https://api.crossref.org/works/{doi}/transform/application/x-bibtex"
headers = {"Accept": "application/x-bibtex"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
else:
print(f"Error: Unable to fetch metadata for DOI {doi}")
print(f"HTTP Status Code: {response.status_code}")
print(f"Response Content: {response.text[:500]}") # Print the first 500 characters of the response for debugging
return None
# Convert BibTeX to CSL format
def convert_bibtex_to_csl(bibtex_data):
# Parse the BibTeX string using pybtex
bib_data = parse_string(bibtex_data, bib_format='bibtex')
# Prepare the CSL format structure
bib_entries = []
for entry in bib_data.entries.values():
# Handle authors
authors = []
for author in entry.persons.get("author", []):
given_names = ' '.join(author.first_names) if author.first_names else ''
family_name = ' '.join(author.last_names) if author.last_names else ''
authors.append({"family": family_name, "given": given_names})
# Create CSL entry
bib_entry = {
"id": entry.key,
"type": "book", # Assuming the DOI is for a book, adjust for articles as needed
"title": entry.fields.get("title", ""),
"author": authors,
"issued": {
"date-parts": [[int(entry.fields.get("year", 0)), 1, 1]] # Default to January 1 of the year
},
"publisher": entry.fields.get("publisher", ""),
"DOI": entry.fields.get("doi", "")
}
bib_entries.append(bib_entry)
return bib_entries
# Example DOI for a book
doi = "10.1016/j.jcss.2024.103615" # Replace with the actual DOI you want to fetch
# doi = "978113806512"
# Initialize the variable to ensure it's always defined
bib_entries_doi = []
# Fetch metadata for DOI
bibtex_data_doi = fetch_metadata_from_doi(doi)
if bibtex_data_doi:
bib_entries_doi = convert_bibtex_to_csl(bibtex_data_doi)
# If no metadata is found, inform the user
if not bib_entries_doi:
print(f"No metadata found for DOI {doi}. Please check the DOI or the CrossRef API response.")
# Convert to CiteProc JSON if entries are available
if bib_entries_doi:
bib_source = CiteProcJSON(bib_entries_doi)
# Load the APA CSL style
bib_style = CitationStylesStyle('apa', validate=False)
# Create the citeproc-py bibliography
bibliography = CitationStylesBibliography(bib_style, bib_source, formatter.html)
# Dynamically create citation objects for each reference in the BibTeX data
citations = []
for entry in bib_entries_doi:
citation_item = CitationItem(entry["id"])
citation = Citation([citation_item])
citations.append(citation)
# Register all citations with the bibliography
for citation in citations:
bibliography.register(citation)
# Define the warning function
def warn(citation_item):
print(f"WARNING: Reference with key '{citation_item.key}' not found in the bibliography.")
# Generate citations for all registered references
print('Citations')
print('---------')
for citation in citations:
print(bibliography.cite(citation, warn))
# Finally, render the bibliography
print('')
print('Bibliography')
print('------------')
for item in bibliography.bibliography():
print(str(item))