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 unit ->
49 t
50(** [create ~url ?doi ?cito ()] creates a reference.
51
52 @param url Unique URL for the reference (required).
53 A URL based on a persistent unique identifier (like DOI) is recommended.
54 @param doi Digital Object Identifier for the reference
55 @param cito Citation Typing Ontology intent annotations
56
57 {b Examples:}
58 {[
59 (* Simple reference with just a URL *)
60 let ref1 = Reference.create
61 ~url:"https://doi.org/10.5281/zenodo.16755947"
62 ()
63
64 (* Reference with DOI *)
65 let ref2 = Reference.create
66 ~url:"https://doi.org/10.5281/zenodo.16755947"
67 ~doi:"10.5281/zenodo.16755947"
68 ()
69
70 (* Reference with CiTO annotations *)
71 let ref3 = Reference.create
72 ~url:"https://doi.org/10.5281/zenodo.16755947"
73 ~doi:"10.5281/zenodo.16755947"
74 ~cito:[`CitesAsRecommendedReading; `UsesMethodIn]
75 ()
76 ]} *)
77
78val make :
79 url:string ->
80 ?doi:string ->
81 ?cito:Cito.t list ->
82 ?unknown:Unknown.t ->
83 unit ->
84 t
85(** [make] is like {!create} but allows setting unknown fields. *)
86
87
88(** {1 Accessors} *)
89
90val url : t -> string
91(** [url t] returns the reference's URL. *)
92
93val doi : t -> string option
94(** [doi t] returns the reference's DOI, if set. *)
95
96val cito : t -> Cito.t list option
97(** [cito t] returns the reference's CiTO annotations, if set. *)
98
99val unknown : t -> Unknown.t
100(** [unknown t] returns unrecognized fields from the JSON. *)
101
102
103(** {1 Comparison} *)
104
105val equal : t -> t -> bool
106(** [equal a b] tests equality between two references.
107
108 References are considered equal if they have the same URL. *)
109
110
111(** {1 Pretty Printing} *)
112
113val pp : Format.formatter -> t -> unit
114(** [pp ppf t] pretty prints a reference to the formatter.
115
116 {b Example output:}
117 {v https://doi.org/10.5281/zenodo.16755947 [DOI: 10.5281/zenodo.16755947] v} *)