From 044baf6af4cc8ff143fb1c265e699b9104a46a7a Mon Sep 17 00:00:00 2001 From: james <81617086+je-cook@users.noreply.github.com> Date: Wed, 27 Aug 2025 11:02:44 +0100 Subject: [PATCH] add annotated references --- annotated_reference.py | 328 ++++++++++++++++++++++++++++++++++++++ csl_reference/__init__.py | 14 +- 2 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 annotated_reference.py diff --git a/annotated_reference.py b/annotated_reference.py new file mode 100644 index 0000000..10dc52d --- /dev/null +++ b/annotated_reference.py @@ -0,0 +1,328 @@ +# generated by datamodel-codegen: +# filename: csl-citation.json +# timestamp: 2025-08-02T07:08:29+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Any + +from pydantic import BaseModel, ConfigDict, Field, RootModel + + +class Schema(Enum): + https___resource_citationstyles_org_schema_latest_input_json_csl_citation_json = "https://resource.citationstyles.org/schema/latest/input/json/csl-citation.json" + + +class Label(str, Enum): + act = "act" + appendix = "appendix" + article_locator = "article-locator" + book = "book" + canon = "canon" + chapter = "chapter" + column = "column" + elocation = "elocation" + equation = "equation" + figure = "figure" + folio = "folio" + issue = "issue" + line = "line" + note = "note" + opus = "opus" + page = "page" + paragraph = "paragraph" + part = "part" + rule = "rule" + scene = "scene" + section = "section" + sub_verbo = "sub-verbo" + supplement = "supplement" + table = "table" + timestamp = "timestamp" + title_locator = "title-locator" + verse = "verse" + version = "version" + volume = "volume" + + +class Properties(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + noteIndex: float | None = None + + +class Type(Enum): + article = "article" + article_journal = "article-journal" + article_magazine = "article-magazine" + article_newspaper = "article-newspaper" + bill = "bill" + book = "book" + broadcast = "broadcast" + chapter = "chapter" + classic = "classic" + collection = "collection" + dataset = "dataset" + document = "document" + entry = "entry" + entry_dictionary = "entry-dictionary" + entry_encyclopedia = "entry-encyclopedia" + event = "event" + figure = "figure" + graphic = "graphic" + hearing = "hearing" + interview = "interview" + legal_case = "legal_case" + legislation = "legislation" + manuscript = "manuscript" + map = "map" + motion_picture = "motion_picture" + musical_score = "musical_score" + pamphlet = "pamphlet" + paper_conference = "paper-conference" + patent = "patent" + performance = "performance" + periodical = "periodical" + personal_communication = "personal_communication" + post = "post" + post_weblog = "post-weblog" + regulation = "regulation" + report = "report" + review = "review" + review_book = "review-book" + software = "software" + song = "song" + speech = "speech" + standard = "standard" + thesis = "thesis" + treaty = "treaty" + webpage = "webpage" + + +class NameVariable1(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + family: str | None = None + given: str | None = None + dropping_particle: str | None = Field(None, alias="dropping-particle") + non_dropping_particle: str | None = Field( + None, alias="non-dropping-particle" + ) + suffix: str | None = None + comma_suffix: str | float | bool | None = Field(None, alias="comma-suffix") + static_ordering: str | float | bool | None = Field( + None, alias="static-ordering" + ) + literal: str | None = None + parse_names: str | float | bool | None = Field(None, alias="parse-names") + + +class NameVariable(RootModel[NameVariable1]): + root: NameVariable1 + + +class DatePart(RootModel[list[str | float]]): + root: list[str | float] + + +class DateVariable1(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + date_parts: list[DatePart] | None = Field( + None, alias="date-parts", max_length=2, min_length=1 + ) + season: str | float | None = None + circa: str | float | bool | None = None + literal: str | None = None + raw: str | None = None + + +class DateVariable(RootModel[DateVariable1]): + root: DateVariable1 = Field( + ..., + description="The CSL input model supports two different date representations: an EDTF string (preferred), and a more structured alternative.", + title="Date content model.", + ) + + +class Items(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + type: Type + id: str | float + citation_key: str | None = Field(None, alias="citation-key") + categories: list[str] | None = None + language: str | None = None + journalAbbreviation: str | None = None + shortTitle: str | None = None + author: list[NameVariable] | None = None + chair: list[NameVariable] | None = None + collection_editor: list[NameVariable] | None = Field( + None, alias="collection-editor" + ) + compiler: list[NameVariable] | None = None + composer: list[NameVariable] | None = None + container_author: list[NameVariable] | None = Field( + None, alias="container-author" + ) + contributor: list[NameVariable] | None = None + curator: list[NameVariable] | None = None + director: list[NameVariable] | None = None + editor: list[NameVariable] | None = None + editorial_director: list[NameVariable] | None = Field( + None, alias="editorial-director" + ) + executive_producer: list[NameVariable] | None = Field( + None, alias="executive-producer" + ) + guest: list[NameVariable] | None = None + host: list[NameVariable] | None = None + interviewer: list[NameVariable] | None = None + illustrator: list[NameVariable] | None = None + narrator: list[NameVariable] | None = None + organizer: list[NameVariable] | None = None + original_author: list[NameVariable] | None = Field( + None, alias="original-author" + ) + performer: list[NameVariable] | None = None + producer: list[NameVariable] | None = None + recipient: list[NameVariable] | None = None + reviewed_author: list[NameVariable] | None = Field( + None, alias="reviewed-author" + ) + script_writer: list[NameVariable] | None = Field( + None, alias="script-writer" + ) + series_creator: list[NameVariable] | None = Field( + None, alias="series-creator" + ) + translator: list[NameVariable] | None = None + accessed: DateVariable | None = None + available_date: DateVariable | None = Field(None, alias="available-date") + event_date: DateVariable | None = Field(None, alias="event-date") + issued: DateVariable | None = None + original_date: DateVariable | None = Field(None, alias="original-date") + submitted: DateVariable | None = None + abstract: str | None = None + annote: str | None = None + archive: str | None = None + archive_collection: str | None = None + archive_location: str | None = None + archive_place: str | None = Field(None, alias="archive-place") + authority: str | None = None + call_number: str | None = Field(None, alias="call-number") + chapter_number: str | float | None = Field(None, alias="chapter-number") + citation_number: str | float | None = Field(None, alias="citation-number") + citation_label: str | None = Field(None, alias="citation-label") + collection_number: str | float | None = Field( + None, alias="collection-number" + ) + collection_title: str | None = Field(None, alias="collection-title") + container_title: str | None = Field(None, alias="container-title") + container_title_short: str | None = Field( + None, alias="container-title-short" + ) + dimensions: str | None = None + division: str | None = None + DOI: str | None = None + edition: str | float | None = None + event: str | None = Field( + None, + description="[Deprecated - use 'event-title' instead. Will be removed in 1.1]", + ) + event_title: str | None = Field(None, alias="event-title") + event_place: str | None = Field(None, alias="event-place") + first_reference_note_number: str | float | None = Field( + None, alias="first-reference-note-number" + ) + genre: str | None = None + ISBN: str | None = None + ISSN: str | None = None + issue: str | float | None = None + jurisdiction: str | None = None + keyword: str | None = None + locator: str | float | None = None + medium: str | None = None + note: str | None = None + number: str | float | None = None + number_of_pages: str | float | None = Field(None, alias="number-of-pages") + number_of_volumes: str | float | None = Field( + None, alias="number-of-volumes" + ) + original_publisher: str | None = Field(None, alias="original-publisher") + original_publisher_place: str | None = Field( + None, alias="original-publisher-place" + ) + original_title: str | None = Field(None, alias="original-title") + page: str | float | None = None + page_first: str | float | None = Field(None, alias="page-first") + part: str | float | None = None + part_title: str | None = Field(None, alias="part-title") + PMCID: str | None = None + PMID: str | None = None + printing: str | float | None = None + publisher: str | None = None + publisher_place: str | None = Field(None, alias="publisher-place") + references: str | None = None + reviewed_genre: str | None = Field(None, alias="reviewed-genre") + reviewed_title: str | None = Field(None, alias="reviewed-title") + scale: str | None = None + section: str | None = None + source: str | None = None + status: str | None = None + supplement: str | float | None = None + title: str | None = None + title_short: str | None = Field(None, alias="title-short") + URL: str | None = None + version: str | None = None + volume: str | float | None = None + volume_title: str | None = Field(None, alias="volume-title") + volume_title_short: str | None = Field(None, alias="volume-title-short") + year_suffix: str | None = Field(None, alias="year-suffix") + custom: dict[str, Any] | None = Field( + None, + description=( + "Used to store additional information that " + "does not have a designated CSL JSON field. " + "The custom field is preferred over the note field for storing custom data, " + "particularly for storing key-value pairs, as the note field is used " + "for user annotations in annotated bibliography styles." + ), + examples=[ + {"short_id": "xyz", "other-ids": ["alternative-id"]}, + {"metadata-double-checked": True}, + ], + title="Custom key-value pairs.", + ) + + +class CitationItem(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + id: str | float + itemData: Items | None = None + prefix: str | None = None + suffix: str | None = None + locator: str | None = None + label: Label | None = None + suppress_author: str | float | bool | None = Field( + None, alias="suppress-author" + ) + author_only: str | float | bool | None = Field(None, alias="author-only") + uris: list[str] | None = None + + +class Model(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + schema_: Schema = Field(..., alias="schema") + citationID: str | float + citationItems: list[CitationItem] | None = None + properties: Properties | None = None diff --git a/csl_reference/__init__.py b/csl_reference/__init__.py index bc291bb..e343f4c 100644 --- a/csl_reference/__init__.py +++ b/csl_reference/__init__.py @@ -3,6 +3,18 @@ # SPDX-License-Identifier: MIT """Package to represent references.""" +import logging + +from csl_reference._annotated_reference import AnnotatedReference from csl_reference._reference import DateVariable, NameVariable, Reference, ReferenceType -__all__ = ["DateVariable", "NameVariable", "Reference", "ReferenceType"] +logger = logging.getLogger(__name__) +logger.setLevel(logging.WARNING) + +__all__ = [ + "AnnotatedReference", + "DateVariable", + "NameVariable", + "Reference", + "ReferenceType", +]