From 42d9417471e0a4f97a2d2897a4c796b712dc99ea Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 29 Jul 2024 00:48:37 -0400 Subject: [PATCH 01/40] create json schema --- hayagriva.schema.json | 273 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 hayagriva.schema.json diff --git a/hayagriva.schema.json b/hayagriva.schema.json new file mode 100644 index 00000000..d638db8e --- /dev/null +++ b/hayagriva.schema.json @@ -0,0 +1,273 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/typst/hayagriva/main/hayagriva.schema.json", + "title": "Hayagriva Bibliography Format", + "description": "A bibliography management format for the modern age.", + "type": "object", + "additionalProperties": false, + "patternProperties": { + "([A-Z]|[a-z]|[0-9]|)+": { + "id": "entry", + "$comment": "The key for a reference item can be series of alphanumeric characters that are uninterrupted by whitespace.", + "type": "object", + "description": "An entry in the bibliography. The citation key for the entry can be any alphanumeric character.", + "properties": { + "type": { + "type": "string", + "enum": [ + "article", + "chapter", + "entry", + "anthos", + "report", + "thesis", + "web", + "scene", + "artwork", + "patent", + "case", + "newspaper", + "legislation", + "manuscript", + "original", + "post", + "misc", + "performance", + "periodical", + "proceedings", + "book", + "blog", + "reference", + "conference", + "anthology", + "repository", + "thread", + "video", + "audio", + "exhibition" + ], + "description": "The media type of the item. Often determines the structure of references." + }, + "title": { + "type": "string", + "description": "The title of the item." + }, + "author": { + "type": [ + "array", + "string" + ], + "items": { + "type": [ + "string", + "object" + ], + "properties": { + "name": { + "type": "string" + }, + "given-name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "suffix": { + "type": "string" + }, + "alias": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true, + "description": "The person or persons primarily responsible for the creation of the item." + }, + "date": { + "type": "string", + "description": "The date at which the item was published." + }, + "parent": { + "anyOf": [ + { + "$ref": "entry" + }, + { + "type": "array", + "items": { + "$ref": "entry" + }, + "minItems": 1, + "uniqueItems": true, + "description": "The item in which the item was published or to which it is strongly associated.", + "$comment": "^ This references the it's parent entry based on the `id`." + } + ] + }, + "editor": { + "type": [ + "array", + "string" + ], + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true, + "description": "The person or persons responsible for selecting and revising the content of the item." + }, + "affiliated": { + "type": "array", + "description": "Persons involved with the item that do not fit `author` or `editor`.", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "translator", + "afterword", + "foreword", + "introduction", + "annotator", + "commentator", + "holder", + "compiler", + "founder", + "collaborator", + "organizer", + "cast-member", + "composer", + "producer", + "executive-producer", + "writer", + "cinematography", + "director", + "illustrator", + "narrator" + ] + }, + "names": { + "type": [ + "string", + "array" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "minItems": 1, + "uniqueItems": true + }, + "call-number": { + "type": "string", + "description": "The number of the item in a library, institution, or collection. Use with `archive`." + }, + "publisher": { + "type": "string", + "description": "Publisher of the item." + }, + "location": { + "type": "string", + "description": "The location at which the item was published or created." + }, + "organization": { + "type": "string", + "description": "The organization at or for which the item was produced." + }, + "issue": { + "type": [ + "number", + "string" + ], + "description": "For an item whose parent has multiple issues, indicates the position in the issue sequence. Also used to indicate the episode number for TV." + }, + "volume": { + "type": [ + "number", + "string" + ], + "description": "For an item whose parent has multiple volumes/parts/seasons ... of which this item is one." + }, + "volume-total": { + "type": "number", + "description": "Total number of volumes/parts/seasons this item consists of." + }, + "edition": { + "type": [ + "number", + "string" + ], + "description": "The published version of an item." + }, + "page-range": { + "type": [ + "number", + "string" + ], + "description": "The range of pages within the parent this item occupies." + }, + "page-total": { + "type": "number", + "description": "total number of pages the item has" + }, + "time-range": { + "type": "string", + "description": "The time range within the parent this item starts and ends at." + }, + "runtime": { + "type": "string", + "description": "The total runtime of the item." + }, + "url": { + "type": [ + "string", + "object" + ], + "description": "The canonical public URL of the item. Can have access date.", + "properties": { + "value": { + "type": "string" + }, + "date": { + "type": "string" + } + } + }, + "serial-number": { + "type": [ + "string", + "object" + ], + "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like doi, you should put them into the serial number as a dictionary like in the second example. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", + "additionalProperties": { + "type": "string" + } + }, + "language": { + "type": "string", + "description": "The language of the item. Must be a Unicode language identifier." + }, + "archive": { + "type": "string", + "description": "The name of the institution or collection where the item is kept." + }, + "arhcive-location": { + "type": "string", + "description": "The location of the institution or collection where the item is kept." + }, + "note": { + "type": "string", + "description": "Any additional description to be appended after reference list entry." + } + } + } + } +} \ No newline at end of file From a5b7df1bf165c124c11f56b1e3b72d623bc33e58 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 29 Jul 2024 18:52:00 -0400 Subject: [PATCH 02/40] add examples from specification using the `examples` keyword --- hayagriva.schema.json | 185 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 162 insertions(+), 23 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index d638db8e..c2fa3846 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -11,9 +11,34 @@ "$comment": "The key for a reference item can be series of alphanumeric characters that are uninterrupted by whitespace.", "type": "object", "description": "An entry in the bibliography. The citation key for the entry can be any alphanumeric character.", + "examples": [ + { + "plaque": { + "type": "Misc", + "title": "Informational plaque about Jacoby's 1967 photos", + "publisher": "Stiftung Reinbeckhallen", + "location": "Berlin, Germany", + "date": 2020, + "parent": { + "type": "Artwork", + "date": 1967, + "author": "Jacoby, Max", + "parent": { + "type": "Anthology", + "title": "Bleibtreustraße", + "archive": "Landesmuseum Koblenz", + "archive-location": "Koblenz, Germany" + } + } + } + } + ], "properties": { "type": { "type": "string", + "examples": [ + "video" + ], "enum": [ "article", "chapter", @@ -50,7 +75,10 @@ }, "title": { "type": "string", - "description": "The title of the item." + "description": "The title of the item.", + "examples": [ + "Rick Astley: How An Internet Joke Revived My Career" + ] }, "author": { "type": [ @@ -85,11 +113,21 @@ }, "minItems": 1, "uniqueItems": true, - "description": "The person or persons primarily responsible for the creation of the item." + "description": "The person or persons primarily responsible for the creation of the item.", + "examples": [ + [ + "Klocke, Iny", + "Wohlrath, Elmar" + ], + "Klocke, Iny" + ] }, "date": { "type": "string", - "description": "The date at which the item was published." + "description": "The date at which the item was published.", + "examples": [ + "1949-05" + ] }, "parent": { "anyOf": [ @@ -104,7 +142,17 @@ "minItems": 1, "uniqueItems": true, "description": "The item in which the item was published or to which it is strongly associated.", - "$comment": "^ This references the it's parent entry based on the `id`." + "$comment": "^ This references the it's parent entry based on the `id`.", + "examples": [ + { + "type": "Anthology", + "title": "Automata studies", + "editor": [ + "Shannon, C. E.", + "McCarthy, J." + ] + } + ] } ] }, @@ -118,11 +166,33 @@ }, "minItems": 1, "uniqueItems": true, - "description": "The person or persons responsible for selecting and revising the content of the item." + "description": "The person or persons responsible for selecting and revising the content of the item.", + "examples": [ + [ + "Stringer, Gary A.", + "Pebworth, Ted-Larry" + ] + ] }, "affiliated": { "type": "array", "description": "Persons involved with the item that do not fit `author` or `editor`.", + "examples": [ + [ + { + "role": "Director", + "names": "Cameron, James" + }, + { + "role": "CastMember", + "names": [ + "Schwarzenegger, Arnold", + "Hamilton, Linda", + "Patrick, Robert" + ] + } + ] + ], "items": { "type": "object", "properties": { @@ -168,63 +238,104 @@ }, "call-number": { "type": "string", - "description": "The number of the item in a library, institution, or collection. Use with `archive`." + "description": "The number of the item in a library, institution, or collection. Use with `archive`.", + "examples": [ + "F16 D14" + ] }, "publisher": { "type": "string", - "description": "Publisher of the item." + "description": "Publisher of the item.", + "examples": [ + "Penguin Books" + ] }, "location": { "type": "string", - "description": "The location at which the item was published or created." + "description": "The location at which the item was published or created.", + "examples": [ + "Lahore, Pakistan" + ] }, "organization": { "type": "string", - "description": "The organization at or for which the item was produced." + "description": "The organization at or for which the item was produced.", + "examples": [ + "Technische Universität Berlin" + ] }, "issue": { "type": [ "number", "string" ], - "description": "For an item whose parent has multiple issues, indicates the position in the issue sequence. Also used to indicate the episode number for TV." + "description": "For an item whose parent has multiple issues, indicates the position in the issue sequence. Also used to indicate the episode number for TV.", + "examples": [ + 5, + "5" + ] }, "volume": { "type": [ "number", "string" ], - "description": "For an item whose parent has multiple volumes/parts/seasons ... of which this item is one." + "description": "For an item whose parent has multiple volumes/parts/seasons ... of which this item is one.", + "examples": [ + "2-3", + 2 + ] }, "volume-total": { "type": "number", - "description": "Total number of volumes/parts/seasons this item consists of." + "description": "Total number of volumes/parts/seasons this item consists of.", + "examples": [ + 12 + ] }, "edition": { "type": [ "number", "string" ], - "description": "The published version of an item." + "description": "The published version of an item.", + "examples": [ + "expanded and revised edition", + "second", + 3 + ] }, "page-range": { "type": [ "number", "string" ], - "description": "The range of pages within the parent this item occupies." + "description": "The range of pages within the parent this item occupies.", + "examples": [ + "812 - 847", + 812 + ] }, "page-total": { "type": "number", - "description": "total number of pages the item has" + "description": "total number of pages the item has", + "examples": [ + 1103 + ] }, "time-range": { "type": "string", - "description": "The time range within the parent this item starts and ends at." + "description": "The time range within the parent this item starts and ends at.", + "examples": [ + "00:57-06:21" + ] }, "runtime": { "type": "string", - "description": "The total runtime of the item." + "description": "The total runtime of the item.", + "examples": [ + "01:42:21,802" + ] }, "url": { "type": [ @@ -239,7 +350,15 @@ "date": { "type": "string" } - } + }, + "examples": [ + { + "url": { + "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", + "date": "2020-12-29" + } + } + ] }, "serial-number": { "type": [ @@ -249,23 +368,43 @@ "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like doi, you should put them into the serial number as a dictionary like in the second example. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", "additionalProperties": { "type": "string" - } + }, + "examples": [ + "2003.13722", + { + "doi": "10.22541/au.148771883.35456290", + "arxiv": "1906.00356", + "serial": "8516" + } + ] }, "language": { "type": "string", - "description": "The language of the item. Must be a Unicode language identifier." + "description": "The language of the item. Must be a Unicode language identifier.", + "examples": [ + "zh-Hans" + ] }, "archive": { "type": "string", - "description": "The name of the institution or collection where the item is kept." + "description": "The name of the institution or collection where the item is kept.", + "examples": [ + "National Library of New Zealand" + ] }, "arhcive-location": { "type": "string", - "description": "The location of the institution or collection where the item is kept." + "description": "The location of the institution or collection where the item is kept.", + "examples": [ + "Wellington, New Zealand" + ] }, "note": { "type": "string", - "description": "Any additional description to be appended after reference list entry." + "description": "Any additional description to be appended after reference list entry.", + "examples": [ + "microfilm version" + ] } } } From 5b0a3a8e6d94bf91f7e1eb36f6894fb28d0284ad Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 29 Jul 2024 20:25:29 -0400 Subject: [PATCH 03/40] use `$dynamicAnchor` and `$dynamicRef` according to the JSON 2020-12 schema --- hayagriva.schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index c2fa3846..56a7f420 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -7,7 +7,7 @@ "additionalProperties": false, "patternProperties": { "([A-Z]|[a-z]|[0-9]|)+": { - "id": "entry", + "$dynamicAnchor": "entry", "$comment": "The key for a reference item can be series of alphanumeric characters that are uninterrupted by whitespace.", "type": "object", "description": "An entry in the bibliography. The citation key for the entry can be any alphanumeric character.", @@ -132,7 +132,7 @@ "parent": { "anyOf": [ { - "$ref": "entry" + "$dynamicRef": "#entry" }, { "type": "array", From ae1f3a2da34195d0fbfe93573a06d03928a16820 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Tue, 30 Jul 2024 16:33:19 -0400 Subject: [PATCH 04/40] update `parent` schema to correctly reference `#entry` if in an array, move description to root of `parent` schema --- hayagriva.schema.json | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 56a7f420..11bb9f19 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -130,28 +130,31 @@ ] }, "parent": { + "description": "The item in which the item was published or to which it is strongly associated.", "anyOf": [ { - "$dynamicRef": "#entry" + "$dynamicRef": "#entry", + "$comment": "^ This references the `entry` schema defined above by the `$dynamicAnchor` keyword." }, { "type": "array", "items": { - "$ref": "entry" + "$dynamicRef": "#entry", + "$comment": "^ This references the `entry` schema defined above by the `$dynamicAnchor` keyword." }, "minItems": 1, "uniqueItems": true, - "description": "The item in which the item was published or to which it is strongly associated.", - "$comment": "^ This references the it's parent entry based on the `id`.", "examples": [ - { - "type": "Anthology", - "title": "Automata studies", - "editor": [ - "Shannon, C. E.", - "McCarthy, J." - ] - } + [ + { + "type": "Anthology", + "title": "Automata studies", + "editor": [ + "Shannon, C. E.", + "McCarthy, J." + ] + } + ] ] } ] From e5ded8a7fa5b02c7a9032b33c6c7590604f3c290 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Thu, 1 Aug 2024 21:19:39 -0400 Subject: [PATCH 05/40] add `abstract`, `annote`, and `genre` to schema --- hayagriva.schema.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 11bb9f19..2aab0d55 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -159,6 +159,24 @@ } ] }, + "abstract": { + "type": "string", + "description": "Abstract of the item (e.g. the abstract of a journal article).", + "examples": [ + "The dominant sequence transduction models are based on complex..." + ] + }, + "annote": { + "type": "string", + "description": "Short markup, decoration, or annotation to the item (e.g., to indicate items included in a review); For descriptive text (e.g., in an annotated bibliography), use `note` instead." + }, + "genre": { + "type": "string", + "description": "Type, class, or subtype of the item (e.g. “Doctoral dissertation” for a PhD thesis; “NIH Publication” for an NIH technical report); Do not use for topical descriptions or categories (e.g. “adventure” for an adventure movie).", + "examples": [ + "Doctoral dissertation" + ] + }, "editor": { "type": [ "array", From 3bab47a7dd3cc0d23d19740e9ff697c9598b3ac1 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 26 Aug 2024 17:38:54 -0400 Subject: [PATCH 06/40] add `annote` example to JSON schema --- hayagriva.schema.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 2aab0d55..7442a307 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -168,7 +168,10 @@ }, "annote": { "type": "string", - "description": "Short markup, decoration, or annotation to the item (e.g., to indicate items included in a review); For descriptive text (e.g., in an annotated bibliography), use `note` instead." + "description": "Short markup, decoration, or annotation to the item (e.g., to indicate items included in a review); For descriptive text (e.g., in an annotated bibliography), use `note` instead.", + "examples": [ + "The researchers at NYU explore in this paper ..." + ] }, "genre": { "type": "string", From 523f2c00cab52566c88be9d902946e0631c4a4c9 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 13:50:33 -0400 Subject: [PATCH 07/40] Hayagriva JSON Schema --- hayagriva.schema.json | 471 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 471 insertions(+) create mode 100644 hayagriva.schema.json diff --git a/hayagriva.schema.json b/hayagriva.schema.json new file mode 100644 index 00000000..8fbb683a --- /dev/null +++ b/hayagriva.schema.json @@ -0,0 +1,471 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Hayagriva Bibliography Format", + "type": "object", + "description": "A bibliography management format for the modern age.", + "additionalProperties": { + "$ref": "#/definitions/entry" + }, + "definitions": { + "entry": { + "type": "object", + "description": "A single bibliography entry.", + "examples": [ + { + "harry": { + "type": "Book", + "title": "Harry Potter and the Order of the Phoenix", + "author": "Rowling, J. K.", + "volume": 5, + "page-total": 768, + "date": "2003-06-21T00:00:00.000Z" + } + }, + { + "electronic": { + "type": "Web", + "title": "Ishkur's Guide to Electronic Music", + "serial-number": "v2.5", + "author": "Ishkur", + "url": "http://www.techno.org/electronic-music-guide/" + } + } + ], + "properties": { + "type": { "$ref": "#/definitions/entryType" }, + "title": { + "description": "The title of this entry", + "examples": ["Rick Astley: How An Internet Joke Revived My Career"], + "$ref": "#/definitions/formattableString" + }, + "author": { + "description": "People primarily responsible for the creation of this entry", + "examples": [["Klocke, Iny", "Wohlrath, Elmar"]], + "oneOf": [ + { + "$ref": "#/definitions/person" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/person" + } + } + ] + }, + "date": { + "description": "The date of publication or creation of this entry", + "$ref": "#/definitions/date" + }, + "parent": { + "description": "Entry in which the current entry was published / to which it is strongly associated to", + "examples": [ + { + "type": "Anthology", + "title": "Automata studies", + "editor": ["Shannon, Claude E.", "McCarthy, John"] + } + ], + "$ref": "#/definitions/parentOrArray" + }, + "abstract": { + "$ref": "#/definitions/formattableString", + "description": "Abstract of the entry", + "examples": [ + "The dominant sequence transduction models are based on complex..." + ] + }, + "genre": { + "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie)", + "$ref": "#/definitions/formattableString", + "examples": ["Doctoral dissertation"] + }, + "editor": { + "description": "People responsible for selecting and revising the content of the entry", + "examples": ["Stringer, Gary A.", "Pebworth, Ted-Larry"], + "$ref": "#/definitions/personOrList" + }, + "affiliated": { + "description": "People involved with the entry that do not fit author or editor roles", + "examples": [ + { + "role": "Director", + "names": "Cameron, James" + }, + { + "role": "CastMember", + "names": [ + "Schwarzenegger, Arnold", + "Hamilton, Linda", + "Patrick, Robert" + ] + } + ], + "$ref": "#/definitions/affiliatedList" + }, + "call-number": { + "$ref": "#/definitions/formattableString", + "description": "The number of the item in a library, institution, or collection. Use with archive", + "examples": ["F16 D14"] + }, + "publisher": { + "description": "The name of the publisher", + "examples": [ + "Penguin Books", + { + "name": "Penguin Books", + "location": "London" + } + ], + "$ref": "#/definitions/publisher" + }, + "location": { + "$ref": "#/definitions/formattableString", + "description": "Location at which the entry is physically located or took place. For the location where an item was published, use publisher instead.", + "examples": ["Lahore, Pakistan"] + }, + "organization": { + "description": "Organization at/for which the entry was produced", + "examples": ["Technische Universität Berlin"], + "$ref": "#/definitions/formattableString" + }, + "issue": { + "$ref": "#/definitions/numericOrString", + "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV", + "examples": [5] + }, + "volume": { + "$ref": "#/definitions/numericOrString", + "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one", + "examples": ["2-3"] + }, + "volume-total": { + "type": "integer", + "examples": [12], + "description": "Total number of volumes, parts, seasons, etc. this entry is part of" + }, + "edition": { + "$ref": "#/definitions/numericOrString", + "description": "Published version of the entry", + "examples": ["expanded and revised edition"] + }, + "page-range": { + "$ref": "#/definitions/numericOrString", + "description": "Range of pages within the parent this entry occupies", + "examples": ["812-847"] + }, + "page-total": { + "type": "integer", + "description": "Total number of pages in the entry", + "examples": [768] + }, + "time-range": { + "description": "The time range within the parent this entry starts and ends at", + "examples": ["00:57-06:21"], + "$ref": "#/definitions/timestampRange" + }, + "runtime": { + "$ref": "#/definitions/timestamp" + }, + "url": { + "$ref": "#/definitions/url" + }, + "serial-number": { + "$ref": "#/definitions/serialNumber" + }, + "language": { + "$ref": "#/definitions/language" + }, + "archive": { + "$ref": "#/definitions/formattableString" + }, + "archive-location": { + "$ref": "#/definitions/formattableString" + }, + "note": { + "$ref": "#/definitions/formattableString" + } + }, + "additionalProperties": false + }, + "publisher": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "location": { + "type": "string" + } + }, + "required": ["name"], + "additionalProperties": false + } + ] + }, + "entryType": { + "type": "string", + "examples": [ + "article", + "chapter", + "entry", + "anthos", + "report", + "thesis", + "web", + "scene", + "artwork", + "patent", + "case", + "newspaper", + "legislation", + "manuscript", + "original", + "post", + "misc", + "performance", + "periodical", + "proceedings", + "book", + "blog", + "reference", + "conference", + "anthology", + "repository", + "thread", + "video", + "audio", + "exhibition" + ], + "description": "Media type of the item, often determines the structure of references.", + "pattern": "^(?i)(article|chapter|entry|anthos|report|thesis|web|scene|artwork|patent|case|newspaper|legislation|manuscript|original|post|misc|performance|periodical|proceedings|book|blog|reference|conference|anthology|repository|thread|video|audio|exhibition)$" + }, + "parentOrArray": { + "oneOf": [ + { + "$ref": "#/definitions/entry" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/entry" + } + } + ] + }, + "affiliatedList": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "$ref": "#/definitions/roleType" + }, + "names": { + "$ref": "#/definitions/personOrList" + } + }, + "required": ["role", "names"], + "additionalProperties": false + } + }, + "roleType": { + "type": "string", + "examples": [ + "translator", + "afterword", + "foreword", + "introduction", + "annotator", + "commentator", + "holder", + "compiler", + "founder", + "collaborator", + "organizer", + "cast-member", + "composer", + "producer", + "executive-producer", + "writer", + "cinematography", + "director", + "illustrator", + "narrator" + ], + "pattern": "^(?i)(translator|afterword|foreword|introduction|annotator|commentator|holder|compiler|founder|collaborator|organizer|cast-member|composer|producer|executive-producer|writer|cinematography|director|illustrator|narrator)$" + }, + "formattableString": { + "description": "A formattable string is a string that may run through a text case transformer when used in a reference or citation. You can disable these transformations on segments of the string or the whole string.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "verbatim": { + "description": "", + "type": "boolean" + }, + "short": { + "type": "string" + } + }, + "required": ["value"] + } + ] + }, + "person": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "given-name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "suffix": { + "type": "string" + }, + "alias": { + "type": "string" + } + }, + "required": ["name"], + "additionalProperties": false + } + ] + }, + "personOrList": { + "oneOf": [ + { + "$ref": "#/definitions/person" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/person" + } + } + ] + }, + "date": { + "anyOf": [ + { + "type": "string", + "format": "date", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "$comment": "YYYY-MM-DD format" + }, + { + "type": "integer", + "minimum": 0, + "$comment": "Year only" + }, + { + "type": "string", + "pattern": "^\\d{4}-\\d{2}$", + "$comment": "YYYY-MM format" + }, + { + "type": "string", + "pattern": "^([+-]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$", + "$comment": "YYYY-MM-DDTHH:MM:SS format" + } + ] + }, + "timestamp": { + "type": "string", + "pattern": "^\\d{1,2}:\\d{2}(:\\d{2})?(,\\d+)?$" + }, + "timestampRange": { + "type": "string", + "pattern": "^\\d{1,2}:\\d{2}(:\\d{2})?(,\\d+)?-\\d{1,2}:\\d{2}(:\\d{2})?(,\\d+)?$" + }, + "numericOrString": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "url": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "date": { + "$ref": "#/definitions/date" + } + }, + "required": ["value"], + "additionalProperties": false + } + ] + }, + "serialNumber": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "doi": { + "type": "string" + }, + "isbn": { + "type": "string" + }, + "issn": { + "type": "string" + }, + "pmid": { + "type": "string" + }, + "pmcid": { + "type": "string" + }, + "arxiv": { + "type": "string" + }, + "serial": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "language": { + "type": "string", + "pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3,4})?(-[A-Z]{2})?$" + } + } +} From a5ebeb6a0bf06c475e38dcae1a226857c654703d Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 16:03:15 -0400 Subject: [PATCH 08/40] done --- hayagriva.schema.json | 299 +++++++++++++++++++++++++++++------------- 1 file changed, 211 insertions(+), 88 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 8fbb683a..b523f14e 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -18,7 +18,7 @@ "author": "Rowling, J. K.", "volume": 5, "page-total": 768, - "date": "2003-06-21T00:00:00.000Z" + "date": "2003-06-21" } }, { @@ -29,6 +29,68 @@ "author": "Ishkur", "url": "http://www.techno.org/electronic-music-guide/" } + }, + { + "kinetics": { + "type": "Article", + "title": "Kinetics and luminescence of the excitations of a nonequilibrium polariton condensate", + "author": ["Doan, T. D.", "Tran Thoai, D. B.", "Haug, Hartmut"], + "serial-number": { + "doi": "10.1103/PhysRevB.102.165126" + }, + "page-range": "165126-165139", + "date": "2020-10-14", + "parent": { + "type": "Periodical", + "title": "Physical Review B", + "volume": 102, + "issue": 16, + "publisher": "American Physical Society" + } + } + }, + { + "wwdc-network": { + "type": "Article", + "author": ["Mehta, Jiten", "Kinnear, Eric"], + "title": "Boost Performance and Security with Modern Networking", + "date": "2020-06-26", + "parent": [ + { + "type": "Conference", + "title": "World Wide Developer Conference 2020", + "organization": "Apple Inc.", + "location": "Mountain View, CA" + }, + { + "type": "Video", + "runtime": "00:13:42", + "url": "https://developer.apple.com/videos/play/wwdc2020/10111/" + } + ] + } + }, + { + "plaque": { + "type": "Misc", + "title": "Informational plaque about Jacoby's 1967 photos", + "publisher": { + "name": "Stiftung Reinbeckhallen", + "location": "Berlin, Germany" + }, + "date": 2020, + "parent": { + "type": "Artwork", + "date": 1967, + "author": "Jacoby, Max", + "parent": { + "type": "Anthology", + "title": "Bleibtreustraße", + "archive": "Landesmuseum Koblenz", + "archive-location": "Koblenz, Germany" + } + } + } } ], "properties": { @@ -40,18 +102,7 @@ }, "author": { "description": "People primarily responsible for the creation of this entry", - "examples": [["Klocke, Iny", "Wohlrath, Elmar"]], - "oneOf": [ - { - "$ref": "#/definitions/person" - }, - { - "type": "array", - "items": { - "$ref": "#/definitions/person" - } - } - ] + "$ref": "#/definitions/personOrList" }, "date": { "description": "The date of publication or creation of this entry", @@ -69,120 +120,113 @@ "$ref": "#/definitions/parentOrArray" }, "abstract": { - "$ref": "#/definitions/formattableString", - "description": "Abstract of the entry", "examples": [ "The dominant sequence transduction models are based on complex..." - ] + ], + "$ref": "#/definitions/formattableString" }, "genre": { - "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie)", - "$ref": "#/definitions/formattableString", - "examples": ["Doctoral dissertation"] + "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie).", + "examples": ["Doctoral dissertation"], + "$ref": "#/definitions/formattableString" }, "editor": { - "description": "People responsible for selecting and revising the content of the entry", - "examples": ["Stringer, Gary A.", "Pebworth, Ted-Larry"], + "description": "People responsible for selecting and revising the content of the entry.", "$ref": "#/definitions/personOrList" }, "affiliated": { - "description": "People involved with the entry that do not fit author or editor roles", - "examples": [ - { - "role": "Director", - "names": "Cameron, James" - }, - { - "role": "CastMember", - "names": [ - "Schwarzenegger, Arnold", - "Hamilton, Linda", - "Patrick, Robert" - ] - } - ], + "description": "People involved with the entry that do not fit author or editor roles.", "$ref": "#/definitions/affiliatedList" }, "call-number": { - "$ref": "#/definitions/formattableString", - "description": "The number of the item in a library, institution, or collection. Use with archive", - "examples": ["F16 D14"] + "description": "The number of the item in a library, institution, or collection. Use with archive.", + "examples": ["F16 D14"], + "$ref": "#/definitions/formattableString" }, "publisher": { - "description": "The name of the publisher", - "examples": [ - "Penguin Books", - { - "name": "Penguin Books", - "location": "London" - } - ], + "description": "The name of the publisher.", "$ref": "#/definitions/publisher" }, "location": { - "$ref": "#/definitions/formattableString", "description": "Location at which the entry is physically located or took place. For the location where an item was published, use publisher instead.", - "examples": ["Lahore, Pakistan"] + "examples": ["Lahore, Pakistan"], + "$ref": "#/definitions/formattableString" }, "organization": { - "description": "Organization at/for which the entry was produced", + "description": "Organization at/for which the entry was produced.", "examples": ["Technische Universität Berlin"], "$ref": "#/definitions/formattableString" }, "issue": { - "$ref": "#/definitions/numericOrString", - "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV", - "examples": [5] + "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV.", + "examples": [5], + "$ref": "#/definitions/numericOrString" }, "volume": { - "$ref": "#/definitions/numericOrString", - "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one", - "examples": ["2-3"] + "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one.", + "examples": ["2-3"], + "$ref": "#/definitions/numericOrString" }, "volume-total": { - "type": "integer", + "description": "Total number of volumes, parts, seasons, etc. this entry is part of.", "examples": [12], - "description": "Total number of volumes, parts, seasons, etc. this entry is part of" + "type": "integer" }, "edition": { - "$ref": "#/definitions/numericOrString", - "description": "Published version of the entry", - "examples": ["expanded and revised edition"] + "description": "Published version of the entry.", + "examples": ["expanded and revised edition"], + "$ref": "#/definitions/numericOrString" }, "page-range": { - "$ref": "#/definitions/numericOrString", - "description": "Range of pages within the parent this entry occupies", - "examples": ["812-847"] + "description": "Range of pages within the parent this entry occupies.", + "examples": ["812-847"], + "$ref": "#/definitions/numericOrString" }, "page-total": { - "type": "integer", - "description": "Total number of pages in the entry", - "examples": [768] + "description": "Total number of pages in the entry.", + "examples": [768], + "type": "integer" }, "time-range": { - "description": "The time range within the parent this entry starts and ends at", - "examples": ["00:57-06:21"], + "description": "The time range within the parent this entry starts and ends at.", "$ref": "#/definitions/timestampRange" }, "runtime": { + "description": "Total runtime of the entry.", "$ref": "#/definitions/timestamp" }, "url": { + "description": "Canonical public URL of the entry, can have access date.", + "examples": [ + { + "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", + "date": "2020-12-29" + } + ], "$ref": "#/definitions/url" }, "serial-number": { + "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", + "$ref": "#/definitions/serialNumber" }, "language": { + "description": "Language of the entry.", "$ref": "#/definitions/language" }, "archive": { + "description": "Name of the institution/collection where the entry is kept.", + "examples": ["National Library of New Zealand"], "$ref": "#/definitions/formattableString" }, "archive-location": { + "description": "Location of the institution/collection where the entry is kept.", + "examples": ["Wellington, New Zealand"], "$ref": "#/definitions/formattableString" }, "note": { + "description": "Short markup, decoration, or annotation to the entry (e.g., to indicate items included in a review).", + "examples": ["microfilm version"], "$ref": "#/definitions/formattableString" } }, @@ -206,6 +250,13 @@ "required": ["name"], "additionalProperties": false } + ], + "examples": [ + "Penguin Books", + { + "name": "Penguin Books", + "location": "London" + } ] }, "entryType": { @@ -260,13 +311,29 @@ }, "affiliatedList": { "type": "array", + "examples": [ + { + "role": "Director", + "names": "Cameron, James" + }, + { + "role": "CastMember", + "names": [ + "Schwarzenegger, Arnold", + "Hamilton, Linda", + "Patrick, Robert" + ] + } + ], "items": { "type": "object", "properties": { "role": { + "description": "Role of the person in relation to the entry.", "$ref": "#/definitions/roleType" }, "names": { + "description": "Names of the persons involved in the role.", "$ref": "#/definitions/personOrList" } }, @@ -301,7 +368,6 @@ "pattern": "^(?i)(translator|afterword|foreword|introduction|annotator|commentator|holder|compiler|founder|collaborator|organizer|cast-member|composer|producer|executive-producer|writer|cinematography|director|illustrator|narrator)$" }, "formattableString": { - "description": "A formattable string is a string that may run through a text case transformer when used in a reference or citation. You can disable these transformations on segments of the string or the whole string.", "oneOf": [ { "type": "string" @@ -313,13 +379,18 @@ "type": "string" }, "verbatim": { - "description": "", + "description": "If true, disables text case transformations.", "type": "boolean" }, "short": { + "description": "Short form that a citation style can choose to render over the longer form.", "type": "string" } }, + "dependencies": { + "verbatim": ["value"], + "short": ["value"] + }, "required": ["value"] } ] @@ -327,27 +398,45 @@ "person": { "oneOf": [ { - "type": "string" + "type": "string", + "examples": [ + "Doe, Janet", + "Luther King, Martin, Jr.", + "UNICEF", + "von der Leyen, Ursula" + ] }, { "type": "object", "properties": { "name": { + "description": "The family name of the person.", "type": "string" }, "given-name": { + "description": "The given name of the person.", "type": "string" }, "prefix": { + "description": "The prefix of the person's name.", "type": "string" }, "suffix": { + "description": "The suffix of the person's name.", "type": "string" }, "alias": { + "description": "An alias for the person.", "type": "string" } }, + "examples": [ + { + "given-name": "Gloria Jean", + "name": "Watkins", + "alias": "bell hooks" + } + ], "required": ["name"], "additionalProperties": false } @@ -367,39 +456,50 @@ ] }, "date": { + "description": "A calendar date as ISO 8601.", "anyOf": [ - { - "type": "string", - "format": "date", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "$comment": "YYYY-MM-DD format" - }, { "type": "integer", "minimum": 0, - "$comment": "Year only" - }, - { - "type": "string", - "pattern": "^\\d{4}-\\d{2}$", - "$comment": "YYYY-MM format" + "examples": [2003], + "description": "Shortened date for year only." }, { "type": "string", - "pattern": "^([+-]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$", - "$comment": "YYYY-MM-DDTHH:MM:SS format" + "format": "date", + "$comment": "ISO 8601 date format (YYYY-MM-DD | YYYY-MM | YYYY).", + "examples": ["2003-06-21", "2003-06", "2003"], + "pattern": "^([+-]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" } ] }, "timestamp": { + "description": "A timestamp represents some time in a piece of media. It is given as a string of the form DD:HH:MM:SS,msms but everything except MM:SS can be omitted. Wrapping the string in double-quotes is necessary due to the colons.", "type": "string", - "pattern": "^\\d{1,2}:\\d{2}(:\\d{2})?(,\\d+)?$" + "examples": [ + "12:34", + "1:12:34", + "2:01:12:34", + "12:34,567", + "1:12:34,567", + "2:01:12:34,567" + ], + "pattern": "^((\\d{1,2}:)?([0-5]?\\d:))?([0-5]?\\d):([0-5]\\d)(,\\d+)?$" }, "timestampRange": { + "description": "A range of timestamps is a string containing two timestamps separated by a hyphen.", "type": "string", - "pattern": "^\\d{1,2}:\\d{2}(:\\d{2})?(,\\d+)?-\\d{1,2}:\\d{2}(:\\d{2})?(,\\d+)?$" + "examples": [ + "00:12-00:34", + "1:00:12-1:00:34", + "2:01:12:34-2:01:12:56", + "00:12,567-00:34,890", + "1:00:12,567-1:00:34,890" + ], + "pattern": "^((\\d{1,2}:)?([0-5]?\\d:)?([0-5]?\\d):([0-5]\\d)(,\\d+)?)-((\\d{1,2}:)?([0-5]?\\d:)?([0-5]?\\d):([0-5]\\d)(,\\d+)?)$" }, "numericOrString": { + "description": "A numeric or string value.", "oneOf": [ { "type": "number" @@ -410,6 +510,7 @@ ] }, "url": { + "description": "Canonical public URL of the entry, can have access date.", "oneOf": [ { "type": "string" @@ -418,9 +519,11 @@ "type": "object", "properties": { "value": { + "description": "The URL value.", "type": "string" }, "date": { + "description": "The access date of the URL.", "$ref": "#/definitions/date" } }, @@ -430,32 +533,48 @@ ] }, "serialNumber": { + "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", "oneOf": [ { "type": "string" }, { "type": "object", + "examples": [ + "2003.13722", + { + "doi": "10.22541/au.148771883.35456290", + "arxiv": "1906.00356", + "serial": "8516" + } + ], "properties": { "doi": { + "description": "Digital Object Identifier.", "type": "string" }, "isbn": { + "description": "International Standard Book Number.", "type": "string" }, "issn": { + "description": "International Standard Serial Number.", "type": "string" }, "pmid": { + "description": "PubMed Identifier.", "type": "string" }, "pmcid": { + "description": "PubMed Central Identifier.", "type": "string" }, "arxiv": { + "description": "arXiv Identifier.", "type": "string" }, "serial": { + "description": "Serial number.", "type": "string" } }, @@ -464,6 +583,10 @@ ] }, "language": { + "description": "Language of the entry.", + "$comment": "Unicode Language Identifier (BCP 47).", + "examples": ["zh-Hans"], + "type": "string", "pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3,4})?(-[A-Z]{2})?$" } From 5284869049b9ccb43ddcc063ea3a13aa81e15a13 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 16:15:59 -0400 Subject: [PATCH 09/40] fmt --- hayagriva.schema.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index b523f14e..b981626d 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -207,7 +207,6 @@ }, "serial-number": { "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", - "$ref": "#/definitions/serialNumber" }, "language": { @@ -586,7 +585,6 @@ "description": "Language of the entry.", "$comment": "Unicode Language Identifier (BCP 47).", "examples": ["zh-Hans"], - "type": "string", "pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3,4})?(-[A-Z]{2})?$" } From e2619b4a2fdd6671b23bd8e2d89ca75388789e45 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 21:48:39 -0400 Subject: [PATCH 10/40] bad title example --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index b981626d..1d0012b2 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -97,7 +97,7 @@ "type": { "$ref": "#/definitions/entryType" }, "title": { "description": "The title of this entry", - "examples": ["Rick Astley: How An Internet Joke Revived My Career"], + "examples": ["\"Rick Astley: How An Internet Joke Revived My Career\""], "$ref": "#/definitions/formattableString" }, "author": { From 223172da7ccda873c2ac5f7d0a672a8f39c5104f Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 22:11:39 -0400 Subject: [PATCH 11/40] order --- hayagriva.schema.json | 244 +++++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 120 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 1d0012b2..2bb5ae3a 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -10,95 +10,14 @@ "entry": { "type": "object", "description": "A single bibliography entry.", - "examples": [ - { - "harry": { - "type": "Book", - "title": "Harry Potter and the Order of the Phoenix", - "author": "Rowling, J. K.", - "volume": 5, - "page-total": 768, - "date": "2003-06-21" - } - }, - { - "electronic": { - "type": "Web", - "title": "Ishkur's Guide to Electronic Music", - "serial-number": "v2.5", - "author": "Ishkur", - "url": "http://www.techno.org/electronic-music-guide/" - } - }, - { - "kinetics": { - "type": "Article", - "title": "Kinetics and luminescence of the excitations of a nonequilibrium polariton condensate", - "author": ["Doan, T. D.", "Tran Thoai, D. B.", "Haug, Hartmut"], - "serial-number": { - "doi": "10.1103/PhysRevB.102.165126" - }, - "page-range": "165126-165139", - "date": "2020-10-14", - "parent": { - "type": "Periodical", - "title": "Physical Review B", - "volume": 102, - "issue": 16, - "publisher": "American Physical Society" - } - } - }, - { - "wwdc-network": { - "type": "Article", - "author": ["Mehta, Jiten", "Kinnear, Eric"], - "title": "Boost Performance and Security with Modern Networking", - "date": "2020-06-26", - "parent": [ - { - "type": "Conference", - "title": "World Wide Developer Conference 2020", - "organization": "Apple Inc.", - "location": "Mountain View, CA" - }, - { - "type": "Video", - "runtime": "00:13:42", - "url": "https://developer.apple.com/videos/play/wwdc2020/10111/" - } - ] - } - }, - { - "plaque": { - "type": "Misc", - "title": "Informational plaque about Jacoby's 1967 photos", - "publisher": { - "name": "Stiftung Reinbeckhallen", - "location": "Berlin, Germany" - }, - "date": 2020, - "parent": { - "type": "Artwork", - "date": 1967, - "author": "Jacoby, Max", - "parent": { - "type": "Anthology", - "title": "Bleibtreustraße", - "archive": "Landesmuseum Koblenz", - "archive-location": "Koblenz, Germany" - } - } - } - } - ], "properties": { "type": { "$ref": "#/definitions/entryType" }, "title": { "description": "The title of this entry", - "examples": ["\"Rick Astley: How An Internet Joke Revived My Career\""], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": [ + "\"Rick Astley: How An Internet Joke Revived My Career\"" + ] }, "author": { "description": "People primarily responsible for the creation of this entry", @@ -110,25 +29,25 @@ }, "parent": { "description": "Entry in which the current entry was published / to which it is strongly associated to", + "$ref": "#/definitions/parentOrArray", "examples": [ { "type": "Anthology", "title": "Automata studies", "editor": ["Shannon, Claude E.", "McCarthy, John"] } - ], - "$ref": "#/definitions/parentOrArray" + ] }, "abstract": { + "$ref": "#/definitions/formattableString", "examples": [ "The dominant sequence transduction models are based on complex..." - ], - "$ref": "#/definitions/formattableString" + ] }, "genre": { "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie).", - "examples": ["Doctoral dissertation"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["Doctoral dissertation"] }, "editor": { "description": "People responsible for selecting and revising the content of the entry.", @@ -140,8 +59,8 @@ }, "call-number": { "description": "The number of the item in a library, institution, or collection. Use with archive.", - "examples": ["F16 D14"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["F16 D14"] }, "publisher": { "description": "The name of the publisher.", @@ -149,28 +68,28 @@ }, "location": { "description": "Location at which the entry is physically located or took place. For the location where an item was published, use publisher instead.", - "examples": ["Lahore, Pakistan"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["Lahore, Pakistan"] }, "organization": { "description": "Organization at/for which the entry was produced.", - "examples": ["Technische Universität Berlin"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["Technische Universität Berlin"] }, "issue": { "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV.", - "examples": [5], - "$ref": "#/definitions/numericOrString" + "$ref": "#/definitions/numericOrString", + "examples": [5] }, "volume": { "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one.", - "examples": ["2-3"], - "$ref": "#/definitions/numericOrString" + "$ref": "#/definitions/numericOrString", + "examples": ["2-3"] }, "volume-total": { "description": "Total number of volumes, parts, seasons, etc. this entry is part of.", - "examples": [12], - "type": "integer" + "type": "integer", + "examples": [12] }, "edition": { "description": "Published version of the entry.", @@ -179,13 +98,13 @@ }, "page-range": { "description": "Range of pages within the parent this entry occupies.", - "examples": ["812-847"], - "$ref": "#/definitions/numericOrString" + "$ref": "#/definitions/numericOrString", + "examples": ["812-847"] }, "page-total": { "description": "Total number of pages in the entry.", - "examples": [768], - "type": "integer" + "type": "integer", + "examples": [768] }, "time-range": { "description": "The time range within the parent this entry starts and ends at.", @@ -197,13 +116,13 @@ }, "url": { "description": "Canonical public URL of the entry, can have access date.", + "$ref": "#/definitions/url", "examples": [ { "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", "date": "2020-12-29" } - ], - "$ref": "#/definitions/url" + ] }, "serial-number": { "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", @@ -215,20 +134,104 @@ }, "archive": { "description": "Name of the institution/collection where the entry is kept.", - "examples": ["National Library of New Zealand"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["National Library of New Zealand"] }, "archive-location": { "description": "Location of the institution/collection where the entry is kept.", - "examples": ["Wellington, New Zealand"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["Wellington, New Zealand"] }, "note": { "description": "Short markup, decoration, or annotation to the entry (e.g., to indicate items included in a review).", - "examples": ["microfilm version"], - "$ref": "#/definitions/formattableString" + "$ref": "#/definitions/formattableString", + "examples": ["microfilm version"] } }, + "examples": [ + { + "harry": { + "type": "Book", + "title": "Harry Potter and the Order of the Phoenix", + "author": "Rowling, J. K.", + "volume": 5, + "page-total": 768, + "date": "2003-06-21" + } + }, + { + "electronic": { + "type": "Web", + "title": "Ishkur's Guide to Electronic Music", + "serial-number": "v2.5", + "author": "Ishkur", + "url": "http://www.techno.org/electronic-music-guide/" + } + }, + { + "kinetics": { + "type": "Article", + "title": "Kinetics and luminescence of the excitations of a nonequilibrium polariton condensate", + "author": ["Doan, T. D.", "Tran Thoai, D. B.", "Haug, Hartmut"], + "serial-number": { + "doi": "10.1103/PhysRevB.102.165126" + }, + "page-range": "165126-165139", + "date": "2020-10-14", + "parent": { + "type": "Periodical", + "title": "Physical Review B", + "volume": 102, + "issue": 16, + "publisher": "American Physical Society" + } + } + }, + { + "wwdc-network": { + "type": "Article", + "author": ["Mehta, Jiten", "Kinnear, Eric"], + "title": "Boost Performance and Security with Modern Networking", + "date": "2020-06-26", + "parent": [ + { + "type": "Conference", + "title": "World Wide Developer Conference 2020", + "organization": "Apple Inc.", + "location": "Mountain View, CA" + }, + { + "type": "Video", + "runtime": "00:13:42", + "url": "https://developer.apple.com/videos/play/wwdc2020/10111/" + } + ] + } + }, + { + "plaque": { + "type": "Misc", + "title": "Informational plaque about Jacoby's 1967 photos", + "publisher": { + "name": "Stiftung Reinbeckhallen", + "location": "Berlin, Germany" + }, + "date": 2020, + "parent": { + "type": "Artwork", + "date": 1967, + "author": "Jacoby, Max", + "parent": { + "type": "Anthology", + "title": "Bleibtreustraße", + "archive": "Landesmuseum Koblenz", + "archive-location": "Koblenz, Germany" + } + } + } + } + ], + "required": ["type", "title"], "additionalProperties": false }, "publisher": { @@ -260,6 +263,8 @@ }, "entryType": { "type": "string", + "description": "Media type of the item, often determines the structure of references.", + "pattern": "^(?i)(article|chapter|entry|anthos|report|thesis|web|scene|artwork|patent|case|newspaper|legislation|manuscript|original|post|misc|performance|periodical|proceedings|book|blog|reference|conference|anthology|repository|thread|video|audio|exhibition)$", "examples": [ "article", "chapter", @@ -291,9 +296,7 @@ "video", "audio", "exhibition" - ], - "description": "Media type of the item, often determines the structure of references.", - "pattern": "^(?i)(article|chapter|entry|anthos|report|thesis|web|scene|artwork|patent|case|newspaper|legislation|manuscript|original|post|misc|performance|periodical|proceedings|book|blog|reference|conference|anthology|repository|thread|video|audio|exhibition)$" + ] }, "parentOrArray": { "oneOf": [ @@ -335,6 +338,7 @@ "description": "Names of the persons involved in the role.", "$ref": "#/definitions/personOrList" } + }, "required": ["role", "names"], "additionalProperties": false @@ -342,6 +346,7 @@ }, "roleType": { "type": "string", + "pattern": "^(?i)(translator|afterword|foreword|introduction|annotator|commentator|holder|compiler|founder|collaborator|organizer|cast-member|composer|producer|executive-producer|writer|cinematography|director|illustrator|narrator)$", "examples": [ "translator", "afterword", @@ -363,8 +368,7 @@ "director", "illustrator", "narrator" - ], - "pattern": "^(?i)(translator|afterword|foreword|introduction|annotator|commentator|holder|compiler|founder|collaborator|organizer|cast-member|composer|producer|executive-producer|writer|cinematography|director|illustrator|narrator)$" + ] }, "formattableString": { "oneOf": [ From baa2a6bf484761c1d53138b031841bb38b7d8bd5 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 22:25:31 -0400 Subject: [PATCH 12/40] title example with single quotes and regex pattern don't support insensitive modifier --- hayagriva.schema.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 2bb5ae3a..2f360bfc 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -15,9 +15,7 @@ "title": { "description": "The title of this entry", "$ref": "#/definitions/formattableString", - "examples": [ - "\"Rick Astley: How An Internet Joke Revived My Career\"" - ] + "examples": ["'Rick Astley: How An Internet Joke Revived My Career'"] }, "author": { "description": "People primarily responsible for the creation of this entry", @@ -264,7 +262,7 @@ "entryType": { "type": "string", "description": "Media type of the item, often determines the structure of references.", - "pattern": "^(?i)(article|chapter|entry|anthos|report|thesis|web|scene|artwork|patent|case|newspaper|legislation|manuscript|original|post|misc|performance|periodical|proceedings|book|blog|reference|conference|anthology|repository|thread|video|audio|exhibition)$", + "pattern": "^(?:[Aa][Rr][Tt][Ii][Cc][Ll][Ee]|[Cc][Hh][Aa][Pp][Tt][Ee][Rr]|[Ee][Nn][Tt][Rr][Yy]|[Aa][Nn][Tt][Hh][Oo][Ss]|[Rr][Ee][Pp][Oo][Rr][Tt]|[Tt][Hh][Ee][Ss][Ii][Ss]|[Ww][Ee][Bb]|[Ss][Cc][Ee][Nn][Ee]|[Aa][Rr][Tt][Ww][Oo][Rr][Kk]|[Pp][Aa][Tt][Ee][Nn][Tt]|[Cc][Aa][Ss][Ee]|[Nn][Ee][Ww][Ss][Pp][Aa][Pp][Ee][Rr]|[Ll][Ee][Gg][Ii][Ss][Ll][Aa][Tt][Ii][Oo][Nn]|[Mm][Aa][Nn][Uu][Ss][Cc][Rr][Ii][Pp][Tt]|[Oo][Rr][Ii][Gg][Ii][Nn][Aa][Ll]|[Pp][Oo][Ss][Tt]|[Mm][Ii][Ss][Cc]|[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Aa][Nn][Cc][Ee]|[Pp][Ee][Rr][Ii][Oo][Dd][Ii][Cc][Aa][Ll]|[Pp][Rr][Oo][Cc][Ee][Ee][Dd][Ii][Nn][Gg][Ss]|[Bb][Oo][Oo][Kk]|[Bb][Ll][Oo][Gg]|[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Cc][Oo][Nn][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Aa][Nn][Tt][Hh][Oo][Ll][Oo][Gg][Yy]|[Rr][Ee][Pp][Oo][Ss][Ii][Tt][Oo][Rr][Yy]|[Tt][Hh][Rr][Ee][Aa][Dd]|[Vv][Ii][Dd][Ee][Oo]|[Aa][Uu][Dd][Ii][Oo]|[Ee][Xx][Hh][Ii][Bb][Ii][Tt][Ii][Oo][Nn])$", "examples": [ "article", "chapter", @@ -338,7 +336,6 @@ "description": "Names of the persons involved in the role.", "$ref": "#/definitions/personOrList" } - }, "required": ["role", "names"], "additionalProperties": false @@ -346,7 +343,7 @@ }, "roleType": { "type": "string", - "pattern": "^(?i)(translator|afterword|foreword|introduction|annotator|commentator|holder|compiler|founder|collaborator|organizer|cast-member|composer|producer|executive-producer|writer|cinematography|director|illustrator|narrator)$", + "pattern": "^(?:[Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Oo][Rr]|[Aa][Ff][Tt][Ee][Rr][Ww][Oo][Rr][Dd]|[Ff][Oo][Rr][Ee][Ww][Oo][Rr][Dd]|[Ii][Nn][Tt][Rr][Oo][Dd][Uu][Cc][Tt][Ii][Oo][Nn]|[Aa][Nn][Nn][Oo][Tt][Aa][Tt][Oo][Rr]|[Cc][Oo][Mm][Mm][Ee][Nn][Tt][Aa][Tt][Oo][Rr]|[Hh][Oo][Ll][Dd][Ee][Rr]|[Cc][Oo][Mm][Pp][Ii][Ll][Ee][Rr]|[Ff][Oo][Uu][Nn][Dd][Ee][Rr]|[Cc][Oo][Ll][Ll][Aa][Bb][Oo][Rr][Aa][Tt][Oo][Rr]|[Oo][Rr][Gg][Aa][Nn][Ii][Zz][Ee][Rr]|[Cc][Aa][Ss][Tt]-[Mm][Ee][Mm][Bb][Ee][Rr]|[Cc][Oo][Mm][Pp][Oo][Ss][Ee][Rr]|[Pp][Rr][Oo][Dd][Uu][Cc][Ee][Rr]|[Ee][Xx][Ee][Cc][Uu][Tt][Ii][Vv][Ee]-[Pp][Rr][Oo][Dd][Uu][Cc][Ee][Rr]|[Ww][Rr][Ii][Tt][Ee][Rr]|[Cc][Ii][Nn][Ee][Mm][Aa][Tt][Oo][Gg][Rr][Aa][Pp][Hh][Yy]|[Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr]|[Ii][Ll][Ll][Uu][Ss][Tt][Rr][Aa][Tt][Oo][Rr]|[Nn][Aa][Rr][Rr][Aa][Tt][Oo][Rr])$", "examples": [ "translator", "afterword", From d0f6d8f53db037e7f139e97c677b19c1de4e53f1 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Sun, 23 Feb 2025 22:27:46 -0400 Subject: [PATCH 13/40] unrequired title because of parents --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 2f360bfc..27c90f94 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -229,7 +229,7 @@ } } ], - "required": ["type", "title"], + "required": ["type"], "additionalProperties": false }, "publisher": { From 69ab709572567fdc626694d63fd93469588df729 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 00:50:51 -0400 Subject: [PATCH 14/40] move examples to defintions and include --- hayagriva.schema.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 27c90f94..a519d6f6 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -114,13 +114,7 @@ }, "url": { "description": "Canonical public URL of the entry, can have access date.", - "$ref": "#/definitions/url", - "examples": [ - { - "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", - "date": "2020-12-29" - } - ] + "$ref": "#/definitions/url" }, "serial-number": { "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", @@ -527,6 +521,13 @@ "$ref": "#/definitions/date" } }, + "examples": [ + "https://typst.app/", + { + "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", + "date": "2020-12-29" + } + ], "required": ["value"], "additionalProperties": false } From a2912fd0f761d3b7422e52452d47cb700f0f9d0c Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:12:44 -0500 Subject: [PATCH 15/40] Use $id instead of $dynamicAnchor for schema recursion --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 7442a307..b954b3c6 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -7,7 +7,7 @@ "additionalProperties": false, "patternProperties": { "([A-Z]|[a-z]|[0-9]|)+": { - "$dynamicAnchor": "entry", + "$id": "entry", "$comment": "The key for a reference item can be series of alphanumeric characters that are uninterrupted by whitespace.", "type": "object", "description": "An entry in the bibliography. The citation key for the entry can be any alphanumeric character.", From db747b540add29db51d725f2d7755bc98d95f7bd Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:13:39 -0500 Subject: [PATCH 16/40] prevent inclusion of unexpected fields for each entry --- hayagriva.schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index b954b3c6..a566fa46 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -11,6 +11,7 @@ "$comment": "The key for a reference item can be series of alphanumeric characters that are uninterrupted by whitespace.", "type": "object", "description": "An entry in the bibliography. The citation key for the entry can be any alphanumeric character.", + "additionalProperties": false, "examples": [ { "plaque": { From ec85829a3277b5d1109aaa11692dc6f32ed4ace1 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:14:44 -0500 Subject: [PATCH 17/40] make entry type case insensitive --- hayagriva.schema.json | 122 +++++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 31 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index a566fa46..fdceb77a 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -40,37 +40,97 @@ "examples": [ "video" ], - "enum": [ - "article", - "chapter", - "entry", - "anthos", - "report", - "thesis", - "web", - "scene", - "artwork", - "patent", - "case", - "newspaper", - "legislation", - "manuscript", - "original", - "post", - "misc", - "performance", - "periodical", - "proceedings", - "book", - "blog", - "reference", - "conference", - "anthology", - "repository", - "thread", - "video", - "audio", - "exhibition" + "oneOf": [ + { + "pattern": "[Aa][Rr][Tt][Ii][Cc][Ll][Ee]" + }, + { + "pattern": "[Cc][Hh][Aa][Pp][Tt][Ee][Rr]" + }, + { + "pattern": "[Ee][Nn][Tt][Rr][Yy]" + }, + { + "pattern": "[Aa][Nn][Tt][Hh][Oo][Ss]" + }, + { + "pattern": "[Rr][Ee][Pp][Oo][Rr][Tt]" + }, + { + "pattern": "[Tt][Hh][Ee][Ss][Ii][Ss]" + }, + { + "pattern": "[Ww][Ee][Bb]" + }, + { + "pattern": "[Ss][Cc][Ee][Nn][Ee]" + }, + { + "pattern": "[Aa][Rr][Tt][Ww][Oo][Rr][Kk]" + }, + { + "pattern": "[Pp][Aa][Tt][Ee][Nn][Tt]" + }, + { + "pattern": "[Cc][Aa][Ss][Ee]" + }, + { + "pattern": "[Nn][Ee][Ww][Ss][Pp][Aa][Pp][Ee][Rr]" + }, + { + "pattern": "[Ll][Ee][Gg][Ii][Ss][Ll][Aa][Tt][Ii][Oo][Nn]" + }, + { + "pattern": "[Mm][Aa][Nn][Uu][Ss][Cc][Rr][Ii][Pp][Tt]" + }, + { + "pattern": "[Oo][Rr][Ii][Gg][Ii][Nn][Aa][Ll]" + }, + { + "pattern": "[Pp][Oo][Ss][Tt]" + }, + { + "pattern": "[Mm][Ii][Ss][Cc]" + }, + { + "pattern": "[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Aa][Nn][Cc][Ee]" + }, + { + "pattern": "[Pp][Ee][Rr][Ii][Oo][Dd][Ii][Cc][Aa][Ll]" + }, + { + "pattern": "[Pp][Rr][Oo][Cc][Ee][Ee][Dd][Ii][Nn][Gg][Ss]" + }, + { + "pattern": "[Bb][Oo][Oo][Kk]" + }, + { + "pattern": "[Bb][Ll][Oo][Gg]" + }, + { + "pattern": "[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee]" + }, + { + "pattern": "[Cc][Oo][Nn][Ff][Ee][Rr][Ee][Nn][Cc][Ee]" + }, + { + "pattern": "[Aa][Nn][Tt][Hh][Oo][Ll][Oo][Gg][Yy]" + }, + { + "pattern": "[Rr][Ee][Pp][Oo][Ss][Ii][Tt][Oo][Rr][Yy]" + }, + { + "pattern": "[Tt][Hh][Rr][Ee][Aa][Dd]" + }, + { + "pattern": "[Vv][Ii][Dd][Ee][Oo]" + }, + { + "pattern": "[Aa][Uu][Dd][Ii][Oo]" + }, + { + "pattern": "[Ee][Xx][Hh][Ii][Bb][Ii][Tt][Ii][Oo][Nn]" + } ], "description": "The media type of the item. Often determines the structure of references." }, From 541b530b7847b24ccfe0ca9772ffb9a9548f3288 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:16:18 -0500 Subject: [PATCH 18/40] allow `title` field to accept objects as well --- hayagriva.schema.json | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index fdceb77a..8ef65c41 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -135,10 +135,28 @@ "description": "The media type of the item. Often determines the structure of references." }, "title": { - "type": "string", "description": "The title of the item.", "examples": [ - "Rick Astley: How An Internet Joke Revived My Career" + "Rick Astley: How An Internet Joke Revived My Career", + { + "value": "Rick Astley: How An Internet Joke Revived My Career", + "verbatim": "true" + } + ], + "type": [ + "string", + "object" + ], + "properties": { + "value": { + "type": "string" + }, + "verbatim": { + "type": "boolean" + } + }, + "required": [ + "value" ] }, "author": { From 377f3a9b7233048cf4a4a5c8289029fb222d60f6 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:19:28 -0500 Subject: [PATCH 19/40] allow integers for the `date` field --- hayagriva.schema.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 8ef65c41..21e85c76 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -202,10 +202,15 @@ ] }, "date": { - "type": "string", + "type": [ + "string", + "integer" + ], "description": "The date at which the item was published.", "examples": [ - "1949-05" + "1949-05-02", + "1949-05", + "1949" ] }, "parent": { From f3a4b80a0e49305d25242bdd83463da469678520 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:21:42 -0500 Subject: [PATCH 20/40] rearrange fields in `author` --- hayagriva.schema.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 21e85c76..6f995fc2 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -160,6 +160,14 @@ ] }, "author": { + "description": "The person or persons primarily responsible for the creation of the item.", + "examples": [ + [ + "Klocke, Iny", + "Wohlrath, Elmar" + ], + "Klocke, Iny" + ], "type": [ "array", "string" @@ -191,15 +199,7 @@ ] }, "minItems": 1, - "uniqueItems": true, - "description": "The person or persons primarily responsible for the creation of the item.", - "examples": [ - [ - "Klocke, Iny", - "Wohlrath, Elmar" - ], - "Klocke, Iny" - ] + "uniqueItems": true }, "date": { "type": [ From 6246e21a89ab2f1235cb16fd5897ca8d1e90f4cf Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:22:09 -0500 Subject: [PATCH 21/40] fix `parent` field --- hayagriva.schema.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 6f995fc2..c805cf36 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -217,14 +217,12 @@ "description": "The item in which the item was published or to which it is strongly associated.", "anyOf": [ { - "$dynamicRef": "#entry", - "$comment": "^ This references the `entry` schema defined above by the `$dynamicAnchor` keyword." + "$ref": "#" }, { "type": "array", "items": { - "$dynamicRef": "#entry", - "$comment": "^ This references the `entry` schema defined above by the `$dynamicAnchor` keyword." + "$ref": "#" }, "minItems": 1, "uniqueItems": true, From 1210d5444ed253587f317fe9fb4a8b8c8527f25b Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:23:08 -0500 Subject: [PATCH 22/40] specify non-floats for certain fields --- hayagriva.schema.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index c805cf36..2469c12a 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -383,7 +383,7 @@ }, "volume": { "type": [ - "number", + "integer", "string" ], "description": "For an item whose parent has multiple volumes/parts/seasons ... of which this item is one.", @@ -393,7 +393,7 @@ ] }, "volume-total": { - "type": "number", + "type": "integer", "description": "Total number of volumes/parts/seasons this item consists of.", "examples": [ 12 @@ -401,7 +401,7 @@ }, "edition": { "type": [ - "number", + "integer", "string" ], "description": "The published version of an item.", @@ -413,7 +413,7 @@ }, "page-range": { "type": [ - "number", + "integer", "string" ], "description": "The range of pages within the parent this item occupies.", @@ -423,7 +423,7 @@ ] }, "page-total": { - "type": "number", + "type": "integer", "description": "total number of pages the item has", "examples": [ 1103 From dd9e0d9b1cd52113c120aff8a504643f3e557599 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:23:30 -0500 Subject: [PATCH 23/40] allow numbers for serial numbers --- hayagriva.schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 2469c12a..0d208e49 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -469,7 +469,8 @@ "serial-number": { "type": [ "string", - "object" + "object", + "number" ], "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like doi, you should put them into the serial number as a dictionary like in the second example. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", "additionalProperties": { From ee04012f2bdfbe9c47bfc50cabe782eda160b59f Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:24:01 -0500 Subject: [PATCH 24/40] fix misspelling of archive --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 0d208e49..d32e3d5d 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -499,7 +499,7 @@ "National Library of New Zealand" ] }, - "arhcive-location": { + "archive-location": { "type": "string", "description": "The location of the institution or collection where the item is kept.", "examples": [ From 48a5cf2d1c853877f65f54a25be7f409859ce08b Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:25:28 -0500 Subject: [PATCH 25/40] add schema validation and `basic.yml` validation --- Cargo.toml | 5 +++++ tests/schema.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/schema.rs diff --git a/Cargo.toml b/Cargo.toml index 0a1e71cd..ccecef55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ strum = { version = "0.26", features = ["derive"], optional = true } heck = "0.5" serde_json = "1" regex = "1" +jsonschema = "0.29.0" [[bin]] name = "hayagriva" @@ -46,3 +47,7 @@ required-features = ["cli"] name = "citeproc" path = "tests/citeproc.rs" required-features = ["csl-json"] + +[[test]] +name = "jsonschema" +path = "tests/schema.rs" diff --git a/tests/schema.rs b/tests/schema.rs new file mode 100644 index 00000000..5ff50438 --- /dev/null +++ b/tests/schema.rs @@ -0,0 +1,44 @@ +use jsonschema; +use serde_json; +use serde_yaml; +use std::fs; +use std::path::Path; +use std::string::String; + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn validate_schema() { + let workspace = Path::new(env!("CARGO_MANIFEST_DIR")); + + let schema_string: String = + fs::read_to_string(workspace.join("hayagriva.schema.json")) + .expect("No file found at specified path."); + + let schema: serde_json::Value = serde_json::from_str(&schema_string) + .expect("String read from file does not contain a valid JSON map."); + + assert!(jsonschema::meta::validate(&schema).is_ok()) + } + + #[test] + fn validate_basic_yaml() { + let workspace = Path::new(env!("CARGO_MANIFEST_DIR")); + + let schema_string: String = + fs::read_to_string(workspace.join("hayagriva.schema.json")) + .expect("No file found at specified path."); + + let schema: serde_json::Value = serde_json::from_str(&schema_string) + .expect("String read from file does not contain a valid JSON map."); + let basic_yml_string: String = + fs::read_to_string(workspace.join("tests/data/basic.yml")) + .expect("No file found at specified path."); + + let basic_yml: serde_json::Value = serde_yaml::from_str(&basic_yml_string) + .expect("String read from file does not contain a valid YAML map."); + + assert!(jsonschema::validate(&schema, &basic_yml).is_ok()); + } +} From 4d63efc817c243c8e314921a9aed656134419494 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 01:30:48 -0500 Subject: [PATCH 26/40] remove redundant imports --- tests/schema.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/schema.rs b/tests/schema.rs index 5ff50438..24395798 100644 --- a/tests/schema.rs +++ b/tests/schema.rs @@ -1,6 +1,3 @@ -use jsonschema; -use serde_json; -use serde_yaml; use std::fs; use std::path::Path; use std::string::String; From cafd358a683c6558c1417c39e47d006782962da7 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 17:11:05 -0400 Subject: [PATCH 27/40] removed format date --- hayagriva.schema.json | 1 - 1 file changed, 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index a519d6f6..a547ddc6 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -460,7 +460,6 @@ }, { "type": "string", - "format": "date", "$comment": "ISO 8601 date format (YYYY-MM-DD | YYYY-MM | YYYY).", "examples": ["2003-06-21", "2003-06", "2003"], "pattern": "^([+-]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" From 288d3ba1374c4e36adc7e74de79eb37e7848a1a5 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 17:12:29 -0400 Subject: [PATCH 28/40] date tilde support --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index a547ddc6..5d8cd533 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -462,7 +462,7 @@ "type": "string", "$comment": "ISO 8601 date format (YYYY-MM-DD | YYYY-MM | YYYY).", "examples": ["2003-06-21", "2003-06", "2003"], - "pattern": "^([+-]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" + "pattern": "^([+-~]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" } ] }, From 06e971ff5ec29834abf0e40e3fd5f1831d4a090e Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 17:17:27 -0400 Subject: [PATCH 29/40] no entry type required --- hayagriva.schema.json | 1 - 1 file changed, 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 5d8cd533..1f14dbd7 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -223,7 +223,6 @@ } } ], - "required": ["type"], "additionalProperties": false }, "publisher": { From 99922b0c7d12457bab9919a2182324f10e2b2303 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 17:19:15 -0400 Subject: [PATCH 30/40] serial number supports strings or numbers --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 1f14dbd7..40959fae 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -535,7 +535,7 @@ "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", "oneOf": [ { - "type": "string" + "type": ["string","number"] }, { "type": "object", From 60d47fd626c65d0c84d7fae8843ee0d3f18fbb17 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 17:43:08 -0400 Subject: [PATCH 31/40] enhance timestamp descriptions and patterns for overflow handling --- hayagriva.schema.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 40959fae..2dd1bf77 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -466,29 +466,31 @@ ] }, "timestamp": { - "description": "A timestamp represents some time in a piece of media. It is given as a string of the form DD:HH:MM:SS,msms but everything except MM:SS can be omitted. Wrapping the string in double-quotes is necessary due to the colons.", + "description": "A timestamp represents some time in a piece of media. It is given as a string of the form DD:HH:MM:SS,msms but everything except MM:SS can be omitted. The left-most time denomination allows values that could overflow into the next-largest denomination if that is not specified.", "type": "string", "examples": [ "12:34", + "137:00", "1:12:34", "2:01:12:34", "12:34,567", "1:12:34,567", "2:01:12:34,567" ], - "pattern": "^((\\d{1,2}:)?([0-5]?\\d:))?([0-5]?\\d):([0-5]\\d)(,\\d+)?$" + "pattern": "^(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?$" }, "timestampRange": { - "description": "A range of timestamps is a string containing two timestamps separated by a hyphen.", + "description": "A range of timestamps is a string containing two timestamps separated by a hyphen. The left-most time denomination in each timestamp allows values that could overflow into the next-largest denomination if that is not specified.", "type": "string", "examples": [ "00:12-00:34", "1:00:12-1:00:34", "2:01:12:34-2:01:12:56", "00:12,567-00:34,890", - "1:00:12,567-1:00:34,890" + "1:00:12,567-1:00:34,890", + "137:00-140:00" ], - "pattern": "^((\\d{1,2}:)?([0-5]?\\d:)?([0-5]?\\d):([0-5]\\d)(,\\d+)?)-((\\d{1,2}:)?([0-5]?\\d:)?([0-5]?\\d):([0-5]\\d)(,\\d+)?)$" + "pattern": "^(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?-(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?$" }, "numericOrString": { "description": "A numeric or string value.", @@ -535,7 +537,7 @@ "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", "oneOf": [ { - "type": ["string","number"] + "type": ["string", "number"] }, { "type": "object", From e79d3dbebec3fc8c62361b3cfe3182a25e84234f Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 18:13:03 -0400 Subject: [PATCH 32/40] examples moved from any of --- hayagriva.schema.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 2dd1bf77..728fad41 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -450,17 +450,16 @@ }, "date": { "description": "A calendar date as ISO 8601.", + "examples": [2025, "2025-12-31", "2025-12", "2000"], "anyOf": [ { "type": "integer", "minimum": 0, - "examples": [2003], "description": "Shortened date for year only." }, { "type": "string", "$comment": "ISO 8601 date format (YYYY-MM-DD | YYYY-MM | YYYY).", - "examples": ["2003-06-21", "2003-06", "2003"], "pattern": "^([+-~]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" } ] From 2d64df5b9e1d66ce88a673b07fec52d59a91b07e Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 18:14:21 -0400 Subject: [PATCH 33/40] removed year only string example --- hayagriva.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 728fad41..f9a06c8b 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -450,7 +450,7 @@ }, "date": { "description": "A calendar date as ISO 8601.", - "examples": [2025, "2025-12-31", "2025-12", "2000"], + "examples": [2025, "2025-12-31", "2025-12"], "anyOf": [ { "type": "integer", From 56c5f4f960283ed5b583dce51c20d68a8dae65ae Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 18:45:29 -0400 Subject: [PATCH 34/40] affiliated list wit unique items --- hayagriva.schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index f9a06c8b..c0cd7910 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -332,7 +332,8 @@ }, "required": ["role", "names"], "additionalProperties": false - } + }, + "uniqueItems": true }, "roleType": { "type": "string", From 1b50fbe4e73fd5ea3c5105f8ea08bb5c77e2ae71 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 18:47:54 -0400 Subject: [PATCH 35/40] arrays with unique items --- hayagriva.schema.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index c0cd7910..cd4b9516 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -298,7 +298,8 @@ "type": "array", "items": { "$ref": "#/definitions/entry" - } + }, + "uniqueItems": true } ] }, @@ -445,7 +446,8 @@ "type": "array", "items": { "$ref": "#/definitions/person" - } + }, + "uniqueItems": true } ] }, From 644dde42b3338b158e6e15c7916bd03d7dd1992d Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 18:51:38 -0400 Subject: [PATCH 36/40] tab size 4 and formatting --- hayagriva.schema.json | 1160 +++++++++++++++++++++-------------------- tests/data/basic.yml | 44 +- 2 files changed, 618 insertions(+), 586 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index cd4b9516..84bf396e 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -1,596 +1,602 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Hayagriva Bibliography Format", - "type": "object", - "description": "A bibliography management format for the modern age.", - "additionalProperties": { - "$ref": "#/definitions/entry" - }, - "definitions": { - "entry": { - "type": "object", - "description": "A single bibliography entry.", - "properties": { - "type": { "$ref": "#/definitions/entryType" }, - "title": { - "description": "The title of this entry", - "$ref": "#/definitions/formattableString", - "examples": ["'Rick Astley: How An Internet Joke Revived My Career'"] - }, - "author": { - "description": "People primarily responsible for the creation of this entry", - "$ref": "#/definitions/personOrList" - }, - "date": { - "description": "The date of publication or creation of this entry", - "$ref": "#/definitions/date" - }, - "parent": { - "description": "Entry in which the current entry was published / to which it is strongly associated to", - "$ref": "#/definitions/parentOrArray", - "examples": [ - { - "type": "Anthology", - "title": "Automata studies", - "editor": ["Shannon, Claude E.", "McCarthy, John"] - } - ] - }, - "abstract": { - "$ref": "#/definitions/formattableString", - "examples": [ - "The dominant sequence transduction models are based on complex..." - ] - }, - "genre": { - "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie).", - "$ref": "#/definitions/formattableString", - "examples": ["Doctoral dissertation"] - }, - "editor": { - "description": "People responsible for selecting and revising the content of the entry.", - "$ref": "#/definitions/personOrList" - }, - "affiliated": { - "description": "People involved with the entry that do not fit author or editor roles.", - "$ref": "#/definitions/affiliatedList" - }, - "call-number": { - "description": "The number of the item in a library, institution, or collection. Use with archive.", - "$ref": "#/definitions/formattableString", - "examples": ["F16 D14"] + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Hayagriva Bibliography Format", + "type": "object", + "description": "A bibliography management format for the modern age.", + "additionalProperties": { + "$ref": "#/definitions/entry" + }, + "definitions": { + "entry": { + "type": "object", + "description": "A single bibliography entry.", + "properties": { + "type": { "$ref": "#/definitions/entryType" }, + "title": { + "description": "The title of this entry", + "$ref": "#/definitions/formattableString", + "examples": [ + "'Rick Astley: How An Internet Joke Revived My Career'" + ] + }, + "author": { + "description": "People primarily responsible for the creation of this entry", + "$ref": "#/definitions/personOrList" + }, + "date": { + "description": "The date of publication or creation of this entry", + "$ref": "#/definitions/date" + }, + "parent": { + "description": "Entry in which the current entry was published / to which it is strongly associated to", + "$ref": "#/definitions/parentOrArray", + "examples": [ + { + "type": "Anthology", + "title": "Automata studies", + "editor": ["Shannon, Claude E.", "McCarthy, John"] + } + ] + }, + "abstract": { + "$ref": "#/definitions/formattableString", + "examples": [ + "The dominant sequence transduction models are based on complex..." + ] + }, + "genre": { + "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie).", + "$ref": "#/definitions/formattableString", + "examples": ["Doctoral dissertation"] + }, + "editor": { + "description": "People responsible for selecting and revising the content of the entry.", + "$ref": "#/definitions/personOrList" + }, + "affiliated": { + "description": "People involved with the entry that do not fit author or editor roles.", + "$ref": "#/definitions/affiliatedList" + }, + "call-number": { + "description": "The number of the item in a library, institution, or collection. Use with archive.", + "$ref": "#/definitions/formattableString", + "examples": ["F16 D14"] + }, + "publisher": { + "description": "The name of the publisher.", + "$ref": "#/definitions/publisher" + }, + "location": { + "description": "Location at which the entry is physically located or took place. For the location where an item was published, use publisher instead.", + "$ref": "#/definitions/formattableString", + "examples": ["Lahore, Pakistan"] + }, + "organization": { + "description": "Organization at/for which the entry was produced.", + "$ref": "#/definitions/formattableString", + "examples": ["Technische Universität Berlin"] + }, + "issue": { + "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV.", + "$ref": "#/definitions/numericOrString", + "examples": [5] + }, + "volume": { + "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one.", + "$ref": "#/definitions/numericOrString", + "examples": ["2-3"] + }, + "volume-total": { + "description": "Total number of volumes, parts, seasons, etc. this entry is part of.", + "type": "integer", + "examples": [12] + }, + "edition": { + "description": "Published version of the entry.", + "examples": ["expanded and revised edition"], + "$ref": "#/definitions/numericOrString" + }, + "page-range": { + "description": "Range of pages within the parent this entry occupies.", + "$ref": "#/definitions/numericOrString", + "examples": ["812-847"] + }, + "page-total": { + "description": "Total number of pages in the entry.", + "type": "integer", + "examples": [768] + }, + "time-range": { + "description": "The time range within the parent this entry starts and ends at.", + "$ref": "#/definitions/timestampRange" + }, + "runtime": { + "description": "Total runtime of the entry.", + "$ref": "#/definitions/timestamp" + }, + "url": { + "description": "Canonical public URL of the entry, can have access date.", + "$ref": "#/definitions/url" + }, + "serial-number": { + "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", + "$ref": "#/definitions/serialNumber" + }, + "language": { + "description": "Language of the entry.", + "$ref": "#/definitions/language" + }, + "archive": { + "description": "Name of the institution/collection where the entry is kept.", + "$ref": "#/definitions/formattableString", + "examples": ["National Library of New Zealand"] + }, + "archive-location": { + "description": "Location of the institution/collection where the entry is kept.", + "$ref": "#/definitions/formattableString", + "examples": ["Wellington, New Zealand"] + }, + "note": { + "description": "Short markup, decoration, or annotation to the entry (e.g., to indicate items included in a review).", + "$ref": "#/definitions/formattableString", + "examples": ["microfilm version"] + } + }, + "examples": [ + { + "harry": { + "type": "Book", + "title": "Harry Potter and the Order of the Phoenix", + "author": "Rowling, J. K.", + "volume": 5, + "page-total": 768, + "date": "2003-06-21" + } + }, + { + "electronic": { + "type": "Web", + "title": "Ishkur's Guide to Electronic Music", + "serial-number": "v2.5", + "author": "Ishkur", + "url": "http://www.techno.org/electronic-music-guide/" + } + }, + { + "kinetics": { + "type": "Article", + "title": "Kinetics and luminescence of the excitations of a nonequilibrium polariton condensate", + "author": [ + "Doan, T. D.", + "Tran Thoai, D. B.", + "Haug, Hartmut" + ], + "serial-number": { + "doi": "10.1103/PhysRevB.102.165126" + }, + "page-range": "165126-165139", + "date": "2020-10-14", + "parent": { + "type": "Periodical", + "title": "Physical Review B", + "volume": 102, + "issue": 16, + "publisher": "American Physical Society" + } + } + }, + { + "wwdc-network": { + "type": "Article", + "author": ["Mehta, Jiten", "Kinnear, Eric"], + "title": "Boost Performance and Security with Modern Networking", + "date": "2020-06-26", + "parent": [ + { + "type": "Conference", + "title": "World Wide Developer Conference 2020", + "organization": "Apple Inc.", + "location": "Mountain View, CA" + }, + { + "type": "Video", + "runtime": "00:13:42", + "url": "https://developer.apple.com/videos/play/wwdc2020/10111/" + } + ] + } + }, + { + "plaque": { + "type": "Misc", + "title": "Informational plaque about Jacoby's 1967 photos", + "publisher": { + "name": "Stiftung Reinbeckhallen", + "location": "Berlin, Germany" + }, + "date": 2020, + "parent": { + "type": "Artwork", + "date": 1967, + "author": "Jacoby, Max", + "parent": { + "type": "Anthology", + "title": "Bleibtreustraße", + "archive": "Landesmuseum Koblenz", + "archive-location": "Koblenz, Germany" + } + } + } + } + ], + "additionalProperties": false }, "publisher": { - "description": "The name of the publisher.", - "$ref": "#/definitions/publisher" - }, - "location": { - "description": "Location at which the entry is physically located or took place. For the location where an item was published, use publisher instead.", - "$ref": "#/definitions/formattableString", - "examples": ["Lahore, Pakistan"] - }, - "organization": { - "description": "Organization at/for which the entry was produced.", - "$ref": "#/definitions/formattableString", - "examples": ["Technische Universität Berlin"] - }, - "issue": { - "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV.", - "$ref": "#/definitions/numericOrString", - "examples": [5] - }, - "volume": { - "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one.", - "$ref": "#/definitions/numericOrString", - "examples": ["2-3"] - }, - "volume-total": { - "description": "Total number of volumes, parts, seasons, etc. this entry is part of.", - "type": "integer", - "examples": [12] - }, - "edition": { - "description": "Published version of the entry.", - "examples": ["expanded and revised edition"], - "$ref": "#/definitions/numericOrString" - }, - "page-range": { - "description": "Range of pages within the parent this entry occupies.", - "$ref": "#/definitions/numericOrString", - "examples": ["812-847"] - }, - "page-total": { - "description": "Total number of pages in the entry.", - "type": "integer", - "examples": [768] - }, - "time-range": { - "description": "The time range within the parent this entry starts and ends at.", - "$ref": "#/definitions/timestampRange" - }, - "runtime": { - "description": "Total runtime of the entry.", - "$ref": "#/definitions/timestamp" - }, - "url": { - "description": "Canonical public URL of the entry, can have access date.", - "$ref": "#/definitions/url" - }, - "serial-number": { - "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", - "$ref": "#/definitions/serialNumber" - }, - "language": { - "description": "Language of the entry.", - "$ref": "#/definitions/language" - }, - "archive": { - "description": "Name of the institution/collection where the entry is kept.", - "$ref": "#/definitions/formattableString", - "examples": ["National Library of New Zealand"] - }, - "archive-location": { - "description": "Location of the institution/collection where the entry is kept.", - "$ref": "#/definitions/formattableString", - "examples": ["Wellington, New Zealand"] - }, - "note": { - "description": "Short markup, decoration, or annotation to the entry (e.g., to indicate items included in a review).", - "$ref": "#/definitions/formattableString", - "examples": ["microfilm version"] - } - }, - "examples": [ - { - "harry": { - "type": "Book", - "title": "Harry Potter and the Order of the Phoenix", - "author": "Rowling, J. K.", - "volume": 5, - "page-total": 768, - "date": "2003-06-21" - } - }, - { - "electronic": { - "type": "Web", - "title": "Ishkur's Guide to Electronic Music", - "serial-number": "v2.5", - "author": "Ishkur", - "url": "http://www.techno.org/electronic-music-guide/" - } - }, - { - "kinetics": { - "type": "Article", - "title": "Kinetics and luminescence of the excitations of a nonequilibrium polariton condensate", - "author": ["Doan, T. D.", "Tran Thoai, D. B.", "Haug, Hartmut"], - "serial-number": { - "doi": "10.1103/PhysRevB.102.165126" - }, - "page-range": "165126-165139", - "date": "2020-10-14", - "parent": { - "type": "Periodical", - "title": "Physical Review B", - "volume": 102, - "issue": 16, - "publisher": "American Physical Society" - } - } + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "location": { + "type": "string" + } + }, + "required": ["name"], + "additionalProperties": false + } + ], + "examples": [ + "Penguin Books", + { + "name": "Penguin Books", + "location": "London" + } + ] }, - { - "wwdc-network": { - "type": "Article", - "author": ["Mehta, Jiten", "Kinnear, Eric"], - "title": "Boost Performance and Security with Modern Networking", - "date": "2020-06-26", - "parent": [ - { - "type": "Conference", - "title": "World Wide Developer Conference 2020", - "organization": "Apple Inc.", - "location": "Mountain View, CA" - }, - { - "type": "Video", - "runtime": "00:13:42", - "url": "https://developer.apple.com/videos/play/wwdc2020/10111/" - } + "entryType": { + "type": "string", + "description": "Media type of the item, often determines the structure of references.", + "pattern": "^(?:[Aa][Rr][Tt][Ii][Cc][Ll][Ee]|[Cc][Hh][Aa][Pp][Tt][Ee][Rr]|[Ee][Nn][Tt][Rr][Yy]|[Aa][Nn][Tt][Hh][Oo][Ss]|[Rr][Ee][Pp][Oo][Rr][Tt]|[Tt][Hh][Ee][Ss][Ii][Ss]|[Ww][Ee][Bb]|[Ss][Cc][Ee][Nn][Ee]|[Aa][Rr][Tt][Ww][Oo][Rr][Kk]|[Pp][Aa][Tt][Ee][Nn][Tt]|[Cc][Aa][Ss][Ee]|[Nn][Ee][Ww][Ss][Pp][Aa][Pp][Ee][Rr]|[Ll][Ee][Gg][Ii][Ss][Ll][Aa][Tt][Ii][Oo][Nn]|[Mm][Aa][Nn][Uu][Ss][Cc][Rr][Ii][Pp][Tt]|[Oo][Rr][Ii][Gg][Ii][Nn][Aa][Ll]|[Pp][Oo][Ss][Tt]|[Mm][Ii][Ss][Cc]|[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Aa][Nn][Cc][Ee]|[Pp][Ee][Rr][Ii][Oo][Dd][Ii][Cc][Aa][Ll]|[Pp][Rr][Oo][Cc][Ee][Ee][Dd][Ii][Nn][Gg][Ss]|[Bb][Oo][Oo][Kk]|[Bb][Ll][Oo][Gg]|[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Cc][Oo][Nn][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Aa][Nn][Tt][Hh][Oo][Ll][Oo][Gg][Yy]|[Rr][Ee][Pp][Oo][Ss][Ii][Tt][Oo][Rr][Yy]|[Tt][Hh][Rr][Ee][Aa][Dd]|[Vv][Ii][Dd][Ee][Oo]|[Aa][Uu][Dd][Ii][Oo]|[Ee][Xx][Hh][Ii][Bb][Ii][Tt][Ii][Oo][Nn])$", + "examples": [ + "article", + "chapter", + "entry", + "anthos", + "report", + "thesis", + "web", + "scene", + "artwork", + "patent", + "case", + "newspaper", + "legislation", + "manuscript", + "original", + "post", + "misc", + "performance", + "periodical", + "proceedings", + "book", + "blog", + "reference", + "conference", + "anthology", + "repository", + "thread", + "video", + "audio", + "exhibition" ] - } }, - { - "plaque": { - "type": "Misc", - "title": "Informational plaque about Jacoby's 1967 photos", - "publisher": { - "name": "Stiftung Reinbeckhallen", - "location": "Berlin, Germany" - }, - "date": 2020, - "parent": { - "type": "Artwork", - "date": 1967, - "author": "Jacoby, Max", - "parent": { - "type": "Anthology", - "title": "Bleibtreustraße", - "archive": "Landesmuseum Koblenz", - "archive-location": "Koblenz, Germany" - } - } - } - } - ], - "additionalProperties": false - }, - "publisher": { - "oneOf": [ - { - "type": "string" + "parentOrArray": { + "oneOf": [ + { + "$ref": "#/definitions/entry" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/entry" + }, + "uniqueItems": true + } + ] }, - { - "type": "object", - "properties": { - "name": { - "type": "string" + "affiliatedList": { + "type": "array", + "examples": [ + { + "role": "Director", + "names": "Cameron, James" + }, + { + "role": "CastMember", + "names": [ + "Schwarzenegger, Arnold", + "Hamilton, Linda", + "Patrick, Robert" + ] + } + ], + "items": { + "type": "object", + "properties": { + "role": { + "description": "Role of the person in relation to the entry.", + "$ref": "#/definitions/roleType" + }, + "names": { + "description": "Names of the persons involved in the role.", + "$ref": "#/definitions/personOrList" + } + }, + "required": ["role", "names"], + "additionalProperties": false }, - "location": { - "type": "string" - } - }, - "required": ["name"], - "additionalProperties": false - } - ], - "examples": [ - "Penguin Books", - { - "name": "Penguin Books", - "location": "London" - } - ] - }, - "entryType": { - "type": "string", - "description": "Media type of the item, often determines the structure of references.", - "pattern": "^(?:[Aa][Rr][Tt][Ii][Cc][Ll][Ee]|[Cc][Hh][Aa][Pp][Tt][Ee][Rr]|[Ee][Nn][Tt][Rr][Yy]|[Aa][Nn][Tt][Hh][Oo][Ss]|[Rr][Ee][Pp][Oo][Rr][Tt]|[Tt][Hh][Ee][Ss][Ii][Ss]|[Ww][Ee][Bb]|[Ss][Cc][Ee][Nn][Ee]|[Aa][Rr][Tt][Ww][Oo][Rr][Kk]|[Pp][Aa][Tt][Ee][Nn][Tt]|[Cc][Aa][Ss][Ee]|[Nn][Ee][Ww][Ss][Pp][Aa][Pp][Ee][Rr]|[Ll][Ee][Gg][Ii][Ss][Ll][Aa][Tt][Ii][Oo][Nn]|[Mm][Aa][Nn][Uu][Ss][Cc][Rr][Ii][Pp][Tt]|[Oo][Rr][Ii][Gg][Ii][Nn][Aa][Ll]|[Pp][Oo][Ss][Tt]|[Mm][Ii][Ss][Cc]|[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Aa][Nn][Cc][Ee]|[Pp][Ee][Rr][Ii][Oo][Dd][Ii][Cc][Aa][Ll]|[Pp][Rr][Oo][Cc][Ee][Ee][Dd][Ii][Nn][Gg][Ss]|[Bb][Oo][Oo][Kk]|[Bb][Ll][Oo][Gg]|[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Cc][Oo][Nn][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Aa][Nn][Tt][Hh][Oo][Ll][Oo][Gg][Yy]|[Rr][Ee][Pp][Oo][Ss][Ii][Tt][Oo][Rr][Yy]|[Tt][Hh][Rr][Ee][Aa][Dd]|[Vv][Ii][Dd][Ee][Oo]|[Aa][Uu][Dd][Ii][Oo]|[Ee][Xx][Hh][Ii][Bb][Ii][Tt][Ii][Oo][Nn])$", - "examples": [ - "article", - "chapter", - "entry", - "anthos", - "report", - "thesis", - "web", - "scene", - "artwork", - "patent", - "case", - "newspaper", - "legislation", - "manuscript", - "original", - "post", - "misc", - "performance", - "periodical", - "proceedings", - "book", - "blog", - "reference", - "conference", - "anthology", - "repository", - "thread", - "video", - "audio", - "exhibition" - ] - }, - "parentOrArray": { - "oneOf": [ - { - "$ref": "#/definitions/entry" - }, - { - "type": "array", - "items": { - "$ref": "#/definitions/entry" - }, - "uniqueItems": true - } - ] - }, - "affiliatedList": { - "type": "array", - "examples": [ - { - "role": "Director", - "names": "Cameron, James" - }, - { - "role": "CastMember", - "names": [ - "Schwarzenegger, Arnold", - "Hamilton, Linda", - "Patrick, Robert" - ] - } - ], - "items": { - "type": "object", - "properties": { - "role": { - "description": "Role of the person in relation to the entry.", - "$ref": "#/definitions/roleType" - }, - "names": { - "description": "Names of the persons involved in the role.", - "$ref": "#/definitions/personOrList" - } + "uniqueItems": true + }, + "roleType": { + "type": "string", + "pattern": "^(?:[Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Oo][Rr]|[Aa][Ff][Tt][Ee][Rr][Ww][Oo][Rr][Dd]|[Ff][Oo][Rr][Ee][Ww][Oo][Rr][Dd]|[Ii][Nn][Tt][Rr][Oo][Dd][Uu][Cc][Tt][Ii][Oo][Nn]|[Aa][Nn][Nn][Oo][Tt][Aa][Tt][Oo][Rr]|[Cc][Oo][Mm][Mm][Ee][Nn][Tt][Aa][Tt][Oo][Rr]|[Hh][Oo][Ll][Dd][Ee][Rr]|[Cc][Oo][Mm][Pp][Ii][Ll][Ee][Rr]|[Ff][Oo][Uu][Nn][Dd][Ee][Rr]|[Cc][Oo][Ll][Ll][Aa][Bb][Oo][Rr][Aa][Tt][Oo][Rr]|[Oo][Rr][Gg][Aa][Nn][Ii][Zz][Ee][Rr]|[Cc][Aa][Ss][Tt]-[Mm][Ee][Mm][Bb][Ee][Rr]|[Cc][Oo][Mm][Pp][Oo][Ss][Ee][Rr]|[Pp][Rr][Oo][Dd][Uu][Cc][Ee][Rr]|[Ee][Xx][Ee][Cc][Uu][Tt][Ii][Vv][Ee]-[Pp][Rr][Oo][Dd][Uu][Cc][Ee][Rr]|[Ww][Rr][Ii][Tt][Ee][Rr]|[Cc][Ii][Nn][Ee][Mm][Aa][Tt][Oo][Gg][Rr][Aa][Pp][Hh][Yy]|[Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr]|[Ii][Ll][Ll][Uu][Ss][Tt][Rr][Aa][Tt][Oo][Rr]|[Nn][Aa][Rr][Rr][Aa][Tt][Oo][Rr])$", + "examples": [ + "translator", + "afterword", + "foreword", + "introduction", + "annotator", + "commentator", + "holder", + "compiler", + "founder", + "collaborator", + "organizer", + "cast-member", + "composer", + "producer", + "executive-producer", + "writer", + "cinematography", + "director", + "illustrator", + "narrator" + ] }, - "required": ["role", "names"], - "additionalProperties": false - }, - "uniqueItems": true - }, - "roleType": { - "type": "string", - "pattern": "^(?:[Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Oo][Rr]|[Aa][Ff][Tt][Ee][Rr][Ww][Oo][Rr][Dd]|[Ff][Oo][Rr][Ee][Ww][Oo][Rr][Dd]|[Ii][Nn][Tt][Rr][Oo][Dd][Uu][Cc][Tt][Ii][Oo][Nn]|[Aa][Nn][Nn][Oo][Tt][Aa][Tt][Oo][Rr]|[Cc][Oo][Mm][Mm][Ee][Nn][Tt][Aa][Tt][Oo][Rr]|[Hh][Oo][Ll][Dd][Ee][Rr]|[Cc][Oo][Mm][Pp][Ii][Ll][Ee][Rr]|[Ff][Oo][Uu][Nn][Dd][Ee][Rr]|[Cc][Oo][Ll][Ll][Aa][Bb][Oo][Rr][Aa][Tt][Oo][Rr]|[Oo][Rr][Gg][Aa][Nn][Ii][Zz][Ee][Rr]|[Cc][Aa][Ss][Tt]-[Mm][Ee][Mm][Bb][Ee][Rr]|[Cc][Oo][Mm][Pp][Oo][Ss][Ee][Rr]|[Pp][Rr][Oo][Dd][Uu][Cc][Ee][Rr]|[Ee][Xx][Ee][Cc][Uu][Tt][Ii][Vv][Ee]-[Pp][Rr][Oo][Dd][Uu][Cc][Ee][Rr]|[Ww][Rr][Ii][Tt][Ee][Rr]|[Cc][Ii][Nn][Ee][Mm][Aa][Tt][Oo][Gg][Rr][Aa][Pp][Hh][Yy]|[Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr]|[Ii][Ll][Ll][Uu][Ss][Tt][Rr][Aa][Tt][Oo][Rr]|[Nn][Aa][Rr][Rr][Aa][Tt][Oo][Rr])$", - "examples": [ - "translator", - "afterword", - "foreword", - "introduction", - "annotator", - "commentator", - "holder", - "compiler", - "founder", - "collaborator", - "organizer", - "cast-member", - "composer", - "producer", - "executive-producer", - "writer", - "cinematography", - "director", - "illustrator", - "narrator" - ] - }, - "formattableString": { - "oneOf": [ - { - "type": "string" + "formattableString": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "verbatim": { + "description": "If true, disables text case transformations.", + "type": "boolean" + }, + "short": { + "description": "Short form that a citation style can choose to render over the longer form.", + "type": "string" + } + }, + "dependencies": { + "verbatim": ["value"], + "short": ["value"] + }, + "required": ["value"] + } + ] }, - { - "type": "object", - "properties": { - "value": { - "type": "string" - }, - "verbatim": { - "description": "If true, disables text case transformations.", - "type": "boolean" - }, - "short": { - "description": "Short form that a citation style can choose to render over the longer form.", - "type": "string" - } - }, - "dependencies": { - "verbatim": ["value"], - "short": ["value"] - }, - "required": ["value"] - } - ] - }, - "person": { - "oneOf": [ - { - "type": "string", - "examples": [ - "Doe, Janet", - "Luther King, Martin, Jr.", - "UNICEF", - "von der Leyen, Ursula" - ] + "person": { + "oneOf": [ + { + "type": "string", + "examples": [ + "Doe, Janet", + "Luther King, Martin, Jr.", + "UNICEF", + "von der Leyen, Ursula" + ] + }, + { + "type": "object", + "properties": { + "name": { + "description": "The family name of the person.", + "type": "string" + }, + "given-name": { + "description": "The given name of the person.", + "type": "string" + }, + "prefix": { + "description": "The prefix of the person's name.", + "type": "string" + }, + "suffix": { + "description": "The suffix of the person's name.", + "type": "string" + }, + "alias": { + "description": "An alias for the person.", + "type": "string" + } + }, + "examples": [ + { + "given-name": "Gloria Jean", + "name": "Watkins", + "alias": "bell hooks" + } + ], + "required": ["name"], + "additionalProperties": false + } + ] }, - { - "type": "object", - "properties": { - "name": { - "description": "The family name of the person.", - "type": "string" - }, - "given-name": { - "description": "The given name of the person.", - "type": "string" - }, - "prefix": { - "description": "The prefix of the person's name.", - "type": "string" - }, - "suffix": { - "description": "The suffix of the person's name.", - "type": "string" - }, - "alias": { - "description": "An alias for the person.", - "type": "string" - } - }, - "examples": [ - { - "given-name": "Gloria Jean", - "name": "Watkins", - "alias": "bell hooks" - } - ], - "required": ["name"], - "additionalProperties": false - } - ] - }, - "personOrList": { - "oneOf": [ - { - "$ref": "#/definitions/person" + "personOrList": { + "oneOf": [ + { + "$ref": "#/definitions/person" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/person" + }, + "uniqueItems": true + } + ] }, - { - "type": "array", - "items": { - "$ref": "#/definitions/person" - }, - "uniqueItems": true - } - ] - }, - "date": { - "description": "A calendar date as ISO 8601.", - "examples": [2025, "2025-12-31", "2025-12"], - "anyOf": [ - { - "type": "integer", - "minimum": 0, - "description": "Shortened date for year only." + "date": { + "description": "A calendar date as ISO 8601.", + "examples": [2025, "2025-12-31", "2025-12"], + "anyOf": [ + { + "type": "integer", + "minimum": 0, + "description": "Shortened date for year only." + }, + { + "type": "string", + "$comment": "ISO 8601 date format (YYYY-MM-DD | YYYY-MM | YYYY).", + "pattern": "^([+-~]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" + } + ] }, - { - "type": "string", - "$comment": "ISO 8601 date format (YYYY-MM-DD | YYYY-MM | YYYY).", - "pattern": "^([+-~]?\\d{4,})(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$" - } - ] - }, - "timestamp": { - "description": "A timestamp represents some time in a piece of media. It is given as a string of the form DD:HH:MM:SS,msms but everything except MM:SS can be omitted. The left-most time denomination allows values that could overflow into the next-largest denomination if that is not specified.", - "type": "string", - "examples": [ - "12:34", - "137:00", - "1:12:34", - "2:01:12:34", - "12:34,567", - "1:12:34,567", - "2:01:12:34,567" - ], - "pattern": "^(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?$" - }, - "timestampRange": { - "description": "A range of timestamps is a string containing two timestamps separated by a hyphen. The left-most time denomination in each timestamp allows values that could overflow into the next-largest denomination if that is not specified.", - "type": "string", - "examples": [ - "00:12-00:34", - "1:00:12-1:00:34", - "2:01:12:34-2:01:12:56", - "00:12,567-00:34,890", - "1:00:12,567-1:00:34,890", - "137:00-140:00" - ], - "pattern": "^(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?-(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?$" - }, - "numericOrString": { - "description": "A numeric or string value.", - "oneOf": [ - { - "type": "number" + "timestamp": { + "description": "A timestamp represents some time in a piece of media. It is given as a string of the form DD:HH:MM:SS,msms but everything except MM:SS can be omitted. The left-most time denomination allows values that could overflow into the next-largest denomination if that is not specified.", + "type": "string", + "examples": [ + "12:34", + "137:00", + "1:12:34", + "2:01:12:34", + "12:34,567", + "1:12:34,567", + "2:01:12:34,567" + ], + "pattern": "^(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?$" + }, + "timestampRange": { + "description": "A range of timestamps is a string containing two timestamps separated by a hyphen. The left-most time denomination in each timestamp allows values that could overflow into the next-largest denomination if that is not specified.", + "type": "string", + "examples": [ + "00:12-00:34", + "1:00:12-1:00:34", + "2:01:12:34-2:01:12:56", + "00:12,567-00:34,890", + "1:00:12,567-1:00:34,890", + "137:00-140:00" + ], + "pattern": "^(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?-(\\d+:[0-5]\\d|\\d{1,2}:[0-5]?\\d:[0-5]\\d|\\d{1,2}:[0-2]?\\d:[0-5]?\\d:[0-5]\\d)(,\\d+)?$" + }, + "numericOrString": { + "description": "A numeric or string value.", + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] }, - { - "type": "string" - } - ] - }, - "url": { - "description": "Canonical public URL of the entry, can have access date.", - "oneOf": [ - { - "type": "string" + "url": { + "description": "Canonical public URL of the entry, can have access date.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "value": { + "description": "The URL value.", + "type": "string" + }, + "date": { + "description": "The access date of the URL.", + "$ref": "#/definitions/date" + } + }, + "examples": [ + "https://typst.app/", + { + "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", + "date": "2020-12-29" + } + ], + "required": ["value"], + "additionalProperties": false + } + ] }, - { - "type": "object", - "properties": { - "value": { - "description": "The URL value.", - "type": "string" - }, - "date": { - "description": "The access date of the URL.", - "$ref": "#/definitions/date" - } - }, - "examples": [ - "https://typst.app/", - { - "value": "https://www.reddit.com/r/AccidentalRenaissance/comments/er1uxd/japanese_opposition_members_trying_to_block_the/", - "date": "2020-12-29" - } - ], - "required": ["value"], - "additionalProperties": false - } - ] - }, - "serialNumber": { - "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", - "oneOf": [ - { - "type": ["string", "number"] + "serialNumber": { + "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", + "oneOf": [ + { + "type": ["string", "number"] + }, + { + "type": "object", + "examples": [ + "2003.13722", + { + "doi": "10.22541/au.148771883.35456290", + "arxiv": "1906.00356", + "serial": "8516" + } + ], + "properties": { + "doi": { + "description": "Digital Object Identifier.", + "type": "string" + }, + "isbn": { + "description": "International Standard Book Number.", + "type": "string" + }, + "issn": { + "description": "International Standard Serial Number.", + "type": "string" + }, + "pmid": { + "description": "PubMed Identifier.", + "type": "string" + }, + "pmcid": { + "description": "PubMed Central Identifier.", + "type": "string" + }, + "arxiv": { + "description": "arXiv Identifier.", + "type": "string" + }, + "serial": { + "description": "Serial number.", + "type": "string" + } + }, + "additionalProperties": false + } + ] }, - { - "type": "object", - "examples": [ - "2003.13722", - { - "doi": "10.22541/au.148771883.35456290", - "arxiv": "1906.00356", - "serial": "8516" - } - ], - "properties": { - "doi": { - "description": "Digital Object Identifier.", - "type": "string" - }, - "isbn": { - "description": "International Standard Book Number.", - "type": "string" - }, - "issn": { - "description": "International Standard Serial Number.", - "type": "string" - }, - "pmid": { - "description": "PubMed Identifier.", - "type": "string" - }, - "pmcid": { - "description": "PubMed Central Identifier.", - "type": "string" - }, - "arxiv": { - "description": "arXiv Identifier.", - "type": "string" - }, - "serial": { - "description": "Serial number.", - "type": "string" - } - }, - "additionalProperties": false + "language": { + "description": "Language of the entry.", + "$comment": "Unicode Language Identifier (BCP 47).", + "examples": ["zh-Hans"], + "type": "string", + "pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3,4})?(-[A-Z]{2})?$" } - ] - }, - "language": { - "description": "Language of the entry.", - "$comment": "Unicode Language Identifier (BCP 47).", - "examples": ["zh-Hans"], - "type": "string", - "pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3,4})?(-[A-Z]{2})?$" } - } } diff --git a/tests/data/basic.yml b/tests/data/basic.yml index 5e71dcb7..40acb5e0 100644 --- a/tests/data/basic.yml +++ b/tests/data/basic.yml @@ -20,7 +20,7 @@ zygos: wwdc-network: type: Article - author: ["Mehta, Jiten", "Kinnear, Eric"] + author: ["Mehta, Jiten", "Kinnear, Eric"] title: Boost Performance and Security with Modern Networking date: 2020-06-26 parent: @@ -32,7 +32,11 @@ wwdc-network: location: Mountain View, CA - type: Video runtime: "00:13:42" - url: { value: https://developer.apple.com/videos/play/wwdc2020/10111/, date: 2020-09-17 } + url: + { + value: https://developer.apple.com/videos/play/wwdc2020/10111/, + date: 2020-09-17, + } omarova-libra: type: Article @@ -100,7 +104,7 @@ science-e-issue: given-name: "Laurenz" alias: "laurmaedje" date: 2020-07-18 - parent: + parent: type: Repository title: Typst url: https://github.com/typst/typst @@ -113,7 +117,8 @@ terminator-2: - role: director names: Cameron, James - role: cast-member - names: ["Schwarzenegger, Arnold", "Hamilton, Linda", "Patrick, Robert"] + names: + ["Schwarzenegger, Arnold", "Hamilton, Linda", "Patrick, Robert"] - role: composer names: Fiedel, Brad date: 1991-07-01 @@ -160,7 +165,8 @@ wire: genre: Drama affiliated: - role: executive-producer - names: ["Simon, David", "Colesberry, Robert F.", "Noble, Nina Kostroff"] + names: + ["Simon, David", "Colesberry, Robert F.", "Noble, Nina Kostroff"] kinetics: type: Article @@ -182,7 +188,16 @@ kinetics: house: type: Article title: Teaching medicine with the help of "Dr. House" - author: ["Jerrentrup, Andreas", "Mueller, Tobias", "Glowalla, Ulrich", "Herder, Meike", "Henrichs, Nadine", "Neubauer, Andreas", "Schaefer, Juergen R."] + author: + [ + "Jerrentrup, Andreas", + "Mueller, Tobias", + "Glowalla, Ulrich", + "Herder, Meike", + "Henrichs, Nadine", + "Neubauer, Andreas", + "Schaefer, Juergen R.", + ] serial-number: doi: 10.1371/journal.pone.0193972 serial: e0193972 @@ -264,7 +279,14 @@ georgia: really-habitable: type: Article title: Defining the Really Habitable Zone - author: ["Pedbost, Marven F.", "Pomalgu, Trillean", "Lintott, Chris", "Eisner, Nora", "Nicholson, Belinda"] + author: + [ + "Pedbost, Marven F.", + "Pomalgu, Trillean", + "Lintott, Chris", + "Eisner, Nora", + "Nicholson, Belinda", + ] date: 2020 serial-number: 2003.13722 url: https://arxiv.org/abs/2003.13722 @@ -277,7 +299,11 @@ electronic-music: title: Ishkur's Guide to Electronic Music serial-number: v2.5 author: Ishkur - url: { value: http://www.techno.org/electronic-music-guide/, date: 2020-11-12 } + url: + { + value: http://www.techno.org/electronic-music-guide/, + date: 2020-11-12, + } mattermost: type: Web @@ -377,7 +403,7 @@ roe-wade: foia: type: Legislation title: Freedom of Information Act - serial-number : Pub. L. No. 107-296, 80 Stat. 250 + serial-number: Pub. L. No. 107-296, 80 Stat. 250 date: 1967 overleaf: From c56dc3d5ecd8cef008b41f29d97ece59fb6d2c35 Mon Sep 17 00:00:00 2001 From: Jassiel Date: Mon, 24 Feb 2025 18:58:45 -0400 Subject: [PATCH 37/40] add schema ID --- hayagriva.schema.json | 1 + 1 file changed, 1 insertion(+) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index 84bf396e..c5847e02 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -1,5 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/typst/hayagriva/main/hayagriva.schema.json", "title": "Hayagriva Bibliography Format", "type": "object", "description": "A bibliography management format for the modern age.", From ea53efb40ae9e2416187729e32f6147fc5dd20ac Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 23:08:50 -0500 Subject: [PATCH 38/40] Edited field descriptions and added examples --- hayagriva.schema.json | 77 ++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index c5847e02..acb40c5e 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -14,22 +14,27 @@ "properties": { "type": { "$ref": "#/definitions/entryType" }, "title": { - "description": "The title of this entry", + "description": "The title of this entry.", "$ref": "#/definitions/formattableString", "examples": [ - "'Rick Astley: How An Internet Joke Revived My Career'" + "Rick Astley: How An Internet Joke Revived My Career", + { + "value": "Rick Astley: How An Internet Joke Revived My Career", + "short": "Rick Astley", + "verbatim": false + } ] }, "author": { - "description": "People primarily responsible for the creation of this entry", + "description": "The person or people primarily responsible for the creation of this entry.", "$ref": "#/definitions/personOrList" }, "date": { - "description": "The date of publication or creation of this entry", + "description": "The date of publication or creation of this entry.", "$ref": "#/definitions/date" }, "parent": { - "description": "Entry in which the current entry was published / to which it is strongly associated to", + "description": "Entry in which the current entry was published, or to which it is strongly associated.", "$ref": "#/definitions/parentOrArray", "examples": [ { @@ -40,105 +45,106 @@ ] }, "abstract": { + "description": "The abstract or summary of the entry.", "$ref": "#/definitions/formattableString", "examples": [ "The dominant sequence transduction models are based on complex..." ] }, "genre": { - "description": "Type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). Do not use for topical descriptions or categories (e.g. \"adventure\" for an adventure movie).", + "description": "The type, class, or subtype of the item (e.g. \"Doctoral dissertation\" for a PhD thesis; \"NIH Publication\" for an NIH technical report). This field is not intended for topical descriptions or categories (e.g. \"adventure\" for an adventure movie).", "$ref": "#/definitions/formattableString", "examples": ["Doctoral dissertation"] }, "editor": { - "description": "People responsible for selecting and revising the content of the entry.", + "description": "The person or people responsible for selecting and revising the content of the entry.", "$ref": "#/definitions/personOrList" }, "affiliated": { - "description": "People involved with the entry that do not fit author or editor roles.", + "description": "The people involved with the entry that do not fit `author` or `editor` roles.", "$ref": "#/definitions/affiliatedList" }, "call-number": { - "description": "The number of the item in a library, institution, or collection. Use with archive.", + "description": "The number of the item in a library, institution, or collection. Use with the `archive` field.", "$ref": "#/definitions/formattableString", "examples": ["F16 D14"] }, "publisher": { - "description": "The name of the publisher.", + "description": "The name of the publisher. The publisher's location also be included.", "$ref": "#/definitions/publisher" }, "location": { - "description": "Location at which the entry is physically located or took place. For the location where an item was published, use publisher instead.", + "description": "The location at which the entry is physically located or took place. For the location where an item was published, use the `publisher` field instead.", "$ref": "#/definitions/formattableString", "examples": ["Lahore, Pakistan"] }, "organization": { - "description": "Organization at/for which the entry was produced.", + "description": "The organization at/for which the entry was produced.", "$ref": "#/definitions/formattableString", "examples": ["Technische Universität Berlin"] }, "issue": { - "description": "For an entry whose parent has multiple issues, indicated the position in the issue sequence. Also used to indicate the episode number for TV.", + "description": "For an entry whose parent has multiple issues, this field identifies to which specific issue the entry belongs. Also used to indicate the episode number for TV series.", "$ref": "#/definitions/numericOrString", "examples": [5] }, "volume": { - "description": "For an entry whose parent has multiple volumes, parts, seasons, etc. of which this entry is one.", + "description": "For an entry whose parent has multiple volumes, parts, seasons, etc., this field identifies to which specific volume the entry belongs.", "$ref": "#/definitions/numericOrString", "examples": ["2-3"] }, "volume-total": { - "description": "Total number of volumes, parts, seasons, etc. this entry is part of.", + "description": "The total number of volumes, parts, seasons, etc., in the series that contains this entry.", "type": "integer", "examples": [12] }, "edition": { - "description": "Published version of the entry.", - "examples": ["expanded and revised edition"], + "description": "The published version of the entry.", + "examples": ["expanded and revised edition", "second", 2], "$ref": "#/definitions/numericOrString" }, "page-range": { - "description": "Range of pages within the parent this entry occupies.", + "description": "The range of pages within that this entry occupies within the parent.", "$ref": "#/definitions/numericOrString", "examples": ["812-847"] }, "page-total": { - "description": "Total number of pages in the entry.", + "description": "The total number of pages in the entry.", "type": "integer", "examples": [768] }, "time-range": { - "description": "The time range within the parent this entry starts and ends at.", + "description": "The time range within the parent at which this entry starts and ends.", "$ref": "#/definitions/timestampRange" }, "runtime": { - "description": "Total runtime of the entry.", + "description": "The total runtime of the entry.", "$ref": "#/definitions/timestamp" }, "url": { - "description": "Canonical public URL of the entry, can have access date.", + "description": "The canonical public URL of the entry, which may include an access date.", "$ref": "#/definitions/url" }, "serial-number": { - "description": "Any serial number, including article numbers. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", + "description": "Any serial number, including article numbers, associated with the entry. If you have serial numbers of well-known schemes like `doi`, you should put them into the serial number as a dictionary. Hayagriva will recognize and specially treat `doi`, `isbn`, `issn`, `pmid`, `pmcid`, and `arxiv`. You can also include `serial` for the serial number when you provide other formats as well.", "$ref": "#/definitions/serialNumber" }, "language": { - "description": "Language of the entry.", + "description": "The language of the entry.", "$ref": "#/definitions/language" }, "archive": { - "description": "Name of the institution/collection where the entry is kept.", + "description": "The name of the institution/collection where the entry is kept.", "$ref": "#/definitions/formattableString", "examples": ["National Library of New Zealand"] }, "archive-location": { - "description": "Location of the institution/collection where the entry is kept.", + "description": "The location of the institution/collection where the entry is kept.", "$ref": "#/definitions/formattableString", "examples": ["Wellington, New Zealand"] }, "note": { - "description": "Short markup, decoration, or annotation to the entry (e.g., to indicate items included in a review).", + "description": "A short markup, decoration, or annotation to the entry (e.g., to indicate items included in a review).", "$ref": "#/definitions/formattableString", "examples": ["microfilm version"] } @@ -261,7 +267,7 @@ }, "entryType": { "type": "string", - "description": "Media type of the item, often determines the structure of references.", + "description": "The media type of the entry. Often determines the structure of references.", "pattern": "^(?:[Aa][Rr][Tt][Ii][Cc][Ll][Ee]|[Cc][Hh][Aa][Pp][Tt][Ee][Rr]|[Ee][Nn][Tt][Rr][Yy]|[Aa][Nn][Tt][Hh][Oo][Ss]|[Rr][Ee][Pp][Oo][Rr][Tt]|[Tt][Hh][Ee][Ss][Ii][Ss]|[Ww][Ee][Bb]|[Ss][Cc][Ee][Nn][Ee]|[Aa][Rr][Tt][Ww][Oo][Rr][Kk]|[Pp][Aa][Tt][Ee][Nn][Tt]|[Cc][Aa][Ss][Ee]|[Nn][Ee][Ww][Ss][Pp][Aa][Pp][Ee][Rr]|[Ll][Ee][Gg][Ii][Ss][Ll][Aa][Tt][Ii][Oo][Nn]|[Mm][Aa][Nn][Uu][Ss][Cc][Rr][Ii][Pp][Tt]|[Oo][Rr][Ii][Gg][Ii][Nn][Aa][Ll]|[Pp][Oo][Ss][Tt]|[Mm][Ii][Ss][Cc]|[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Aa][Nn][Cc][Ee]|[Pp][Ee][Rr][Ii][Oo][Dd][Ii][Cc][Aa][Ll]|[Pp][Rr][Oo][Cc][Ee][Ee][Dd][Ii][Nn][Gg][Ss]|[Bb][Oo][Oo][Kk]|[Bb][Ll][Oo][Gg]|[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Cc][Oo][Nn][Ff][Ee][Rr][Ee][Nn][Cc][Ee]|[Aa][Nn][Tt][Hh][Oo][Ll][Oo][Gg][Yy]|[Rr][Ee][Pp][Oo][Ss][Ii][Tt][Oo][Rr][Yy]|[Tt][Hh][Rr][Ee][Aa][Dd]|[Vv][Ii][Dd][Ee][Oo]|[Aa][Uu][Dd][Ii][Oo]|[Ee][Xx][Hh][Ii][Bb][Ii][Tt][Ii][Oo][Nn])$", "examples": [ "article", @@ -330,11 +336,11 @@ "type": "object", "properties": { "role": { - "description": "Role of the person in relation to the entry.", + "description": "The role of the person or people in relation to the entry.", "$ref": "#/definitions/roleType" }, "names": { - "description": "Names of the persons involved in the role.", + "description": "The name(s) of the person or people involved in the role.", "$ref": "#/definitions/personOrList" } }, @@ -385,7 +391,7 @@ "type": "boolean" }, "short": { - "description": "Short form that a citation style can choose to render over the longer form.", + "description": "A short form that a citation style can choose to render over the longer form.", "type": "string" } }, @@ -437,6 +443,11 @@ "given-name": "Gloria Jean", "name": "Watkins", "alias": "bell hooks" + }, + { + "given-name": "Ursula", + "name": "Le Guin", + "alias":"Ursula K. Le Guin" } ], "required": ["name"], @@ -459,7 +470,7 @@ ] }, "date": { - "description": "A calendar date as ISO 8601.", + "description": "A calendar date in ISO 8601 format.", "examples": [2025, "2025-12-31", "2025-12"], "anyOf": [ { @@ -593,7 +604,7 @@ ] }, "language": { - "description": "Language of the entry.", + "description": "The Language of the entry.", "$comment": "Unicode Language Identifier (BCP 47).", "examples": ["zh-Hans"], "type": "string", From 524892466b813161556115dc4e06722b2a86bbd2 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 23:10:06 -0500 Subject: [PATCH 39/40] disallow additional properties for `formattableString`'s object variant --- hayagriva.schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hayagriva.schema.json b/hayagriva.schema.json index acb40c5e..bdcc1cae 100644 --- a/hayagriva.schema.json +++ b/hayagriva.schema.json @@ -399,7 +399,8 @@ "verbatim": ["value"], "short": ["value"] }, - "required": ["value"] + "required": ["value"], + "additionalProperties": false } ] }, From 6136ce0ba581a499354dd59c8c3e549d67bf6ad1 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Mon, 24 Feb 2025 23:14:34 -0500 Subject: [PATCH 40/40] remove `sentence-case` field from title --- tests/data/basic.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/data/basic.yml b/tests/data/basic.yml index 40acb5e0..097012b2 100644 --- a/tests/data/basic.yml +++ b/tests/data/basic.yml @@ -43,7 +43,6 @@ omarova-libra: author: ["Omarova, Saule", "Steele, Graham"] title: value: There’s a Lot We Still Don’t Know About Libra - sentence-case: There’s a lot we still don’t know about Libra date: 2019-11-04 url: https://www.nytimes.com/2019/11/04/opinion/facebook-libra-cryptocurrency.html parent: