OCaml library for JSONfeed parsing and creation
1(*---------------------------------------------------------------------------
2 Copyright (c) 2024 Anil Madhavapeddy. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** References extension for JSON Feed items.
7
8 This implements the references extension that allows items to cite sources.
9 Each reference represents a cited resource with optional DOI and CiTO annotations.
10
11 @see <https://github.com/egonw/JSONFeed-extensions/blob/main/references.md> References Extension Specification
12 @see <https://purl.archive.org/spar/cito> Citation Typing Ontology *)
13
14
15(** The type representing a reference to a cited source. *)
16type t
17
18
19(** {1 Unknown Fields} *)
20
21module Unknown : sig
22 type t = (string * Jsont.json) list
23 (** Unknown/unrecognized JSON object members.
24 Useful for preserving fields from custom extensions or future spec versions. *)
25
26 val empty : t
27 (** [empty] is the empty list of unknown fields. *)
28
29 val is_empty : t -> bool
30 (** [is_empty u] returns [true] if there are no unknown fields. *)
31end
32
33
34(** {1 Jsont Type} *)
35
36val jsont : t Jsont.t
37(** Declarative JSON type for references.
38
39 Maps JSON objects with "url" (required) and optional "doi" and "cito" fields. *)
40
41
42(** {1 Construction} *)
43
44val create :
45 url:string ->
46 ?doi:string ->
47 ?cito:Cito.t list ->
48 ?unknown:Unknown.t ->
49 unit ->
50 t
51(** [create ~url ?doi ?cito ?unknown ()] creates a reference.
52
53 @param url Unique URL for the reference (required).
54 A URL based on a persistent unique identifier (like DOI) is recommended.
55 @param doi Digital Object Identifier for the reference
56 @param cito Citation Typing Ontology intent annotations
57 @param unknown Unknown/custom fields for extensions (default: empty)
58
59 {b Examples:}
60 {[
61 (* Simple reference with just a URL *)
62 let ref1 = Reference.create
63 ~url:"https://doi.org/10.5281/zenodo.16755947"
64 ()
65
66 (* Reference with DOI *)
67 let ref2 = Reference.create
68 ~url:"https://doi.org/10.5281/zenodo.16755947"
69 ~doi:"10.5281/zenodo.16755947"
70 ()
71
72 (* Reference with CiTO annotations *)
73 let ref3 = Reference.create
74 ~url:"https://doi.org/10.5281/zenodo.16755947"
75 ~doi:"10.5281/zenodo.16755947"
76 ~cito:[`CitesAsRecommendedReading; `UsesMethodIn]
77 ()
78 ]} *)
79
80
81(** {1 Accessors} *)
82
83val url : t -> string
84(** [url t] returns the reference's URL. *)
85
86val doi : t -> string option
87(** [doi t] returns the reference's DOI, if set. *)
88
89val cito : t -> Cito.t list option
90(** [cito t] returns the reference's CiTO annotations, if set. *)
91
92val unknown : t -> Unknown.t
93(** [unknown t] returns unrecognized fields from the JSON. *)
94
95
96(** {1 Comparison} *)
97
98val equal : t -> t -> bool
99(** [equal a b] tests equality between two references.
100
101 References are considered equal if they have the same URL. *)
102
103
104(** {1 Pretty Printing} *)
105
106val pp : Format.formatter -> t -> unit
107(** [pp ppf t] pretty prints a reference to the formatter.
108
109 {b Example output:}
110 {v https://doi.org/10.5281/zenodo.16755947 [DOI: 10.5281/zenodo.16755947] v} *)