Skip to content

Commit

Permalink
input: Align date-parts and edtf string models (#301)
Browse files Browse the repository at this point in the history
This modifies the structured date object to align with the EDTF model.

It moves the qualifiers to the date object, and then defines a date
range as an array of these date objects.

The result is that dates can either be represented as an EDTF string,
or as a structured object date, or a date range array.

It also replaces the `date-parts` array with simple properties for the 
date parts.

The intention is the structured variants will go away in time, so that
in the future the only option will be the EDTF string.

Closes #300
  • Loading branch information
bdarcus authored Jul 10, 2020
1 parent 5e69fcd commit 892334e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 57 deletions.
167 changes: 119 additions & 48 deletions schemas/input/csl-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,125 @@
"additionalProperties": false
},
"definitions": {
"edtf-string": {
"title": "EDTF date string",
"description": "CSL input supports EDTF, levels 0 and 1.",
"type": "string",
"pattern": "^[0-9-%~X?./]{4,}$"
},
"date-object": {
"title": "Date Object",
"description": "An EDTF date represented as an object. Seasons can be represented using the 21-24 month values of EDTF, decades and centuries using the X notation, and the qualifiers with the included boolean properties",
"examples": [
{
"id": "one",
"type": "book",
"title": "The Title",
"issued": {
"year": 2000,
"month": 3,
"day": 10
},
"approximate": "true"
}
],
"type": "object",
"properties": {
"year": {
"title": "year",
"description": "A year; can be negative.",
"examples": ["2012", "-32"],
"type": "integer"
},
"month": {
"title": "month",
"description": "A month; can also represent seasons using the EDTF 21-24 values.",
"examples": ["2", "22"],
"type": "integer"
},
"day": {
"title": "day",
"type": "integer"
},
"literal": {
"title": "Literal date",
"description": "A date that should be passed through to the processor as is; for dates that cannot be represented in EDTF.",
"examples": ["Han Dynasty"],
"type": "string"
},
"approximate": {
"title": "Approximate",
"description": "Indicates an approximate or circa date, which may be presented as `circa May 23, 1972`.",
"type": "boolean"
},
"uncertain": {
"title": "Uncertain",
"description": "Indicates uncertainty about a date representation, which may be presented as `May 23, 1972?`",
"type": "boolean"
},
"undefined": {
"title": "Undefined",
"description": "Use to represent an open end of a range.",
"type": "boolean"
}
},
"oneOf": [
{
"required": ["year"]
},
{
"required": ["undefined"]
}
]
},
"date-range": {
"title": "Date Range",
"description": "An EDTF range is a two-item array. An open end or beginning of a range can be represented with an empty (date) object.",
"type": "array",
"examples": [
{
"id": "range-1",
"type": "book",
"title": "The Title",
"issued": [{ "year": 2000 }, { "year": 2001 }]
},
{
"id": "range-2",
"type": "book",
"title": "The Title",
"issued": [{ "year": 2000 }, { "undefined": true }]
}
],
"items": {
"$ref": "#/definitions/date-object"
},
"minItems": 2,
"maxItems": 2
},
"date-structured": {
"title": "Structured Date",
"description": "Can either be an object, or a two-item array.",
"oneOf": [
{
"$ref": "#/definitions/date-object"
},
{
"$ref": "#/definitions/date-range"
}
]
},
"date-variable": {
"title": "Date content model.",
"description": "The CSL input model supports two different date representations: an EDTF string (preferred), and a more structured alternative.",
"oneOf": [
{
"$ref": "#/definitions/edtf-string"
},
{
"$ref": "#/definitions/date-structured"
}
]
},
"name-variable": {
"anyOf": [
{
Expand Down Expand Up @@ -472,54 +591,6 @@
"additionalProperties": false
}
]
},
"edtf-datatype": {
"title": "EDTF datatype pattern",
"description": "CSL input supports EDTF, validated against this regular expression.",
"type": "string",
"pattern": "^[0-9-%~X?.\/]{4,}$"
},
"date-variable": {
"title": "Date content model.",
"description": "The CSL input model supports two different date representations: an EDTF string (preferred), and a more structured alternative.",
"anyOf": [
{
"$ref": "#/definitions/edtf-datatype"
},
{
"properties": {
"date-parts": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": ["string", "number"]
},
"minItems": 1,
"maxItems": 3
},
"minItems": 1,
"maxItems": 2
},
"season": {
"type": ["string", "number"]
},
"circa": {
"type": ["string", "number", "boolean"]
},
"literal": {
"type": "string"
},
"raw": {
"type": "string"
},
"edtf": {
"$ref": "#/definitions/edtf-datatype"
}
},
"additionalProperties": false
}
]
}
}
}
18 changes: 9 additions & 9 deletions tests/schemas/input/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,35 +111,35 @@ def test_basic_citation_schema_validates(csl_citation_validator):

def test_basic_data_schema_with_author_validates(csl_data_validator):
csl = [{
'id': 'example-id',
'type': 'report',
"id": "example-id",
"type": "report",
"author": [
{"given": "Jane", "family": "Roe"},
{"literal": "John Doe"}
],
]
}]
csl_data_validator.validate(csl)


def test_data_schema_with_extra_property_fails(csl_data_validator):
csl = [{
'id': 'example-id',
'type': 'report',
'not-a-csl-key': None,
"id": "example-id",
"type": "report",
"not-a-csl-key": None
}]
with pytest.raises(jsonschema.exceptions.ValidationError):
csl_data_validator.validate(csl)

def test_data_schema_with_empty_date_parts(csl_data_validator):
def test_data_schema_with_missing_date(csl_data_validator):
"""
empty arrays in date-parts can cause downstream citeproc failures
empty dates can cause downstream citeproc failures
https://github.com/citation-style-language/schema/pull/158
"""
csl = [{
'id': 'example-id',
'type': 'report',
'issued': {
"date-parts": []
'approximate': True
},
}]
with pytest.raises(jsonschema.exceptions.ValidationError):
Expand Down

0 comments on commit 892334e

Please sign in to comment.