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
10 annotations.
11
12 @see <https://github.com/egonw/JSONFeed-extensions/blob/main/references.md>
13 References Extension Specification
14 @see <https://purl.archive.org/spar/cito> Citation Typing Ontology *)
15
16type t
17(** The type representing a reference to a cited source. *)
18
19(** {1 Unknown Fields} *)
20
21module Unknown : sig
22 type t = Jsont.json
23 (** Unknown/unrecognized JSON object members as a generic JSON object. Useful
24 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(** {1 Jsont Type} *)
34
35val jsont : t Jsont.t
36(** Declarative JSON type for references.
37
38 Maps JSON objects with "url" (required) and optional "doi" and "cito"
39 fields. *)
40
41(** {1 Construction} *)
42
43val create :
44 url:string ->
45 ?doi:string ->
46 ?cito:Cito.t list ->
47 ?unknown:Unknown.t ->
48 unit ->
49 t
50(** [create ~url ?doi ?cito ?unknown ()] creates a reference.
51
52 @param url
53 Unique URL for the reference (required). A URL based on a persistent
54 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 =
63 Reference.create ~url:"https://doi.org/10.5281/zenodo.16755947" ()
64
65 (* Reference with DOI *)
66 let ref2 =
67 Reference.create ~url:"https://doi.org/10.5281/zenodo.16755947"
68 ~doi:"10.5281/zenodo.16755947" ()
69
70 (* Reference with CiTO annotations *)
71 let ref3 =
72 Reference.create ~url:"https://doi.org/10.5281/zenodo.16755947"
73 ~doi:"10.5281/zenodo.16755947"
74 ~cito:[ `CitesAsRecommendedReading; `UsesMethodIn ]
75 ()
76 ]} *)
77
78(** {1 Accessors} *)
79
80val url : t -> string
81(** [url t] returns the reference's URL. *)
82
83val doi : t -> string option
84(** [doi t] returns the reference's DOI, if set. *)
85
86val cito : t -> Cito.t list option
87(** [cito t] returns the reference's CiTO annotations, if set. *)
88
89val unknown : t -> Unknown.t
90(** [unknown t] returns unrecognized fields from the JSON. *)
91
92(** {1 Comparison} *)
93
94val equal : t -> t -> bool
95(** [equal a b] tests equality between two references.
96
97 References are considered equal if they have the same URL. *)
98
99(** {1 Pretty Printing} *)
100
101val pp : Format.formatter -> t -> unit
102(** [pp ppf t] pretty prints a reference to the formatter.
103
104 {b Example output:}
105 {v https://doi.org/10.5281/zenodo.16755947 [DOI: 10.5281/zenodo.16755947] v}
106*)