···2727module Identifier = Cff_identifier
2828module Reference = Cff_reference
29293030-(* Include the root type *)
3131-include Cff_root
3030+(* Root CFF type - integrated directly *)
3131+3232+type t = {
3333+ cff_version : string;
3434+ message : string;
3535+ title : string;
3636+ authors : Cff_author.t list;
3737+ abstract : string option;
3838+ commit : string option;
3939+ contact : Cff_author.t list option;
4040+ date_released : Cff_date.t option;
4141+ doi : string option;
4242+ identifiers : Cff_identifier.t list option;
4343+ keywords : string list option;
4444+ license : Cff_license.t option;
4545+ license_url : string option;
4646+ preferred_citation : Cff_reference.t option;
4747+ references : Cff_reference.t list option;
4848+ repository : string option;
4949+ repository_artifact : string option;
5050+ repository_code : string option;
5151+ type_ : Cff_enums.Cff_type.t option;
5252+ url : string option;
5353+ version : string option;
5454+}
5555+5656+let default_cff_version = "1.2.0"
5757+let default_message = "If you use this software, please cite it using the metadata from this file."
5858+5959+let make
6060+ ?(cff_version = default_cff_version)
6161+ ?(message = default_message)
6262+ ~title
6363+ ~authors
6464+ ?abstract
6565+ ?commit
6666+ ?contact
6767+ ?date_released
6868+ ?doi
6969+ ?identifiers
7070+ ?keywords
7171+ ?license
7272+ ?license_url
7373+ ?preferred_citation
7474+ ?references
7575+ ?repository
7676+ ?repository_artifact
7777+ ?repository_code
7878+ ?type_
7979+ ?url
8080+ ?version
8181+ () =
8282+ { cff_version; message; title; authors;
8383+ abstract; commit; contact; date_released; doi;
8484+ identifiers; keywords; license; license_url;
8585+ preferred_citation; references; repository;
8686+ repository_artifact; repository_code; type_; url; version }
8787+8888+(* Required field accessors *)
8989+let cff_version t = t.cff_version
9090+let message t = t.message
9191+let title t = t.title
9292+let authors t = t.authors
9393+9494+(* Optional field accessors *)
9595+let abstract t = t.abstract
9696+let commit t = t.commit
9797+let contact t = t.contact
9898+let date_released t = t.date_released
9999+let doi t = t.doi
100100+let identifiers t = t.identifiers
101101+let keywords t = t.keywords
102102+let license t = t.license
103103+let license_url t = t.license_url
104104+let preferred_citation t = t.preferred_citation
105105+let references t = t.references
106106+let repository t = t.repository
107107+let repository_artifact t = t.repository_artifact
108108+let repository_code t = t.repository_code
109109+let type_ t = t.type_
110110+let url t = t.url
111111+let version t = t.version
112112+113113+let pp ppf t =
114114+ Format.fprintf ppf "@[<v>";
115115+ Format.fprintf ppf "cff-version: %s@," t.cff_version;
116116+ Format.fprintf ppf "title: %s@," t.title;
117117+ Format.fprintf ppf "message: %s@," t.message;
118118+ Format.fprintf ppf "authors:@,";
119119+ List.iter (fun a -> Format.fprintf ppf " - %a@," Cff_author.pp a) t.authors;
120120+ Option.iter (fun v -> Format.fprintf ppf "version: %s@," v) t.version;
121121+ Option.iter (fun v -> Format.fprintf ppf "doi: %s@," v) t.doi;
122122+ Option.iter (fun v -> Format.fprintf ppf "date-released: %a@," Cff_date.pp v) t.date_released;
123123+ Option.iter (fun v -> Format.fprintf ppf "license: %a@," Cff_license.pp v) t.license;
124124+ Option.iter (fun v -> Format.fprintf ppf "url: %s@," v) t.url;
125125+ Option.iter (fun v -> Format.fprintf ppf "repository: %s@," v) t.repository;
126126+ Option.iter (fun v -> Format.fprintf ppf "repository-code: %s@," v) t.repository_code;
127127+ Option.iter (fun v -> Format.fprintf ppf "abstract: %s@," v) t.abstract;
128128+ Option.iter (fun v -> Format.fprintf ppf "commit: %s@," v) t.commit;
129129+ Option.iter (fun v -> Format.fprintf ppf "type: %a@," Cff_enums.Cff_type.pp v) t.type_;
130130+ Option.iter (fun kws ->
131131+ Format.fprintf ppf "keywords:@,";
132132+ List.iter (fun k -> Format.fprintf ppf " - %s@," k) kws
133133+ ) t.keywords;
134134+ Option.iter (fun ids ->
135135+ Format.fprintf ppf "identifiers:@,";
136136+ List.iter (fun id -> Format.fprintf ppf " - %a@," Cff_identifier.pp id) ids
137137+ ) t.identifiers;
138138+ Option.iter (fun contacts ->
139139+ Format.fprintf ppf "contact:@,";
140140+ List.iter (fun c -> Format.fprintf ppf " - %a@," Cff_author.pp c) contacts
141141+ ) t.contact;
142142+ Option.iter (fun refs ->
143143+ Format.fprintf ppf "references:@,";
144144+ List.iter (fun r -> Format.fprintf ppf " - %a@," Cff_reference.pp r) refs
145145+ ) t.references;
146146+ Option.iter (fun pc ->
147147+ Format.fprintf ppf "preferred-citation:@, %a@," Cff_reference.pp pc
148148+ ) t.preferred_citation;
149149+ Format.fprintf ppf "@]"
150150+151151+let list_jsont elt = Jsont.(array elt |> map ~dec:Stdlib.Array.to_list ~enc:Stdlib.Array.of_list)
152152+153153+let jsont =
154154+ let open Jsont in
155155+ let authors_jsont = list_jsont Cff_author.jsont in
156156+ let identifiers_jsont = list_jsont Cff_identifier.jsont in
157157+ let references_jsont = list_jsont Cff_reference.jsont in
158158+ let keywords_jsont = list_jsont string in
159159+ Object.map ~kind:"CFF"
160160+ (fun cff_version message title authors abstract commit contact
161161+ date_released doi identifiers keywords license license_url
162162+ preferred_citation references repository repository_artifact
163163+ repository_code type_ url version ->
164164+ { cff_version; message; title; authors;
165165+ abstract; commit; contact; date_released; doi;
166166+ identifiers; keywords; license; license_url;
167167+ preferred_citation; references; repository;
168168+ repository_artifact; repository_code; type_; url; version })
169169+ |> Object.mem "cff-version" string ~enc:(fun t -> t.cff_version)
170170+ |> Object.mem "message" string ~enc:(fun t -> t.message)
171171+ |> Object.mem "title" string ~enc:(fun t -> t.title)
172172+ |> Object.mem "authors" authors_jsont ~enc:(fun t -> t.authors)
173173+ |> Object.opt_mem "abstract" string ~enc:(fun t -> t.abstract)
174174+ |> Object.opt_mem "commit" string ~enc:(fun t -> t.commit)
175175+ |> Object.opt_mem "contact" authors_jsont ~enc:(fun t -> t.contact)
176176+ |> Object.opt_mem "date-released" Cff_date.jsont ~enc:(fun t -> t.date_released)
177177+ |> Object.opt_mem "doi" string ~enc:(fun t -> t.doi)
178178+ |> Object.opt_mem "identifiers" identifiers_jsont ~enc:(fun t -> t.identifiers)
179179+ |> Object.opt_mem "keywords" keywords_jsont ~enc:(fun t -> t.keywords)
180180+ |> Object.opt_mem "license" Cff_license.jsont_lenient ~enc:(fun t -> t.license)
181181+ |> Object.opt_mem "license-url" string ~enc:(fun t -> t.license_url)
182182+ |> Object.opt_mem "preferred-citation" Cff_reference.jsont ~enc:(fun t -> t.preferred_citation)
183183+ |> Object.opt_mem "references" references_jsont ~enc:(fun t -> t.references)
184184+ |> Object.opt_mem "repository" string ~enc:(fun t -> t.repository)
185185+ |> Object.opt_mem "repository-artifact" string ~enc:(fun t -> t.repository_artifact)
186186+ |> Object.opt_mem "repository-code" string ~enc:(fun t -> t.repository_code)
187187+ |> Object.opt_mem "type" Cff_enums.Cff_type.jsont ~enc:(fun t -> t.type_)
188188+ |> Object.opt_mem "url" string ~enc:(fun t -> t.url)
189189+ |> Object.opt_mem "version" string ~enc:(fun t -> t.version)
190190+ |> Object.finish
+214-4
lib/cff.mli
···3030 {[
3131 let author = Cff.Author.Person
3232 (Cff.Person.make ~family_names:"Smith" ~given_names:"Jane" ()) in
3333- let cff = Cff.make_simple
3333+ let cff = Cff.make
3434 ~title:"My Research Software"
3535 ~authors:[author]
3636 ~version:"1.0.0"
···188188189189(** {1 Root CFF Type}
190190191191- The main [t] type represents a complete [CITATION.cff] file. It includes
192192- the {!module:Cff_root} interface with all required and optional fields. *)
191191+ The main [t] type represents a complete [CITATION.cff] file with all
192192+ required and optional fields from the CFF 1.2.0 specification.
193193+194194+ {2 Required Fields}
195195+196196+ Every valid CFF file must include:
197197+ - {!cff_version}: Schema version (defaults to ["1.2.0"])
198198+ - {!message}: Instructions for citing the work (has sensible default)
199199+ - {!title}: Name of the software or dataset
200200+ - {!authors}: List of persons and/or entities
201201+202202+ {2 Common Optional Fields}
203203+204204+ - {!version}: Software version string
205205+ - {!doi}: Digital Object Identifier
206206+ - {!date_released}: Publication/release date
207207+ - {!license}: SPDX license identifier(s)
208208+ - {!keywords}: Descriptive keywords
209209+ - {!abstract}: Description of the work
210210+211211+ {2 Citation Redirection}
212212+213213+ The {!preferred_citation} field allows redirecting citations to
214214+ a related work (e.g., a journal article describing the software).
215215+ The {!references} field lists works that the software cites or
216216+ depends upon. *)
217217+218218+(** The abstract type representing a complete CFF document. *)
219219+type t
220220+221221+(** {1 Construction} *)
222222+223223+val default_cff_version : string
224224+(** The default CFF version used when not specified: ["1.2.0"]. *)
225225+226226+val default_message : string
227227+(** The default citation message:
228228+ ["If you use this software, please cite it using the metadata from this file."] *)
229229+230230+val make :
231231+ ?cff_version:string ->
232232+ ?message:string ->
233233+ title:string ->
234234+ authors:Cff_author.t list ->
235235+ ?abstract:string ->
236236+ ?commit:string ->
237237+ ?contact:Cff_author.t list ->
238238+ ?date_released:Cff_date.t ->
239239+ ?doi:string ->
240240+ ?identifiers:Cff_identifier.t list ->
241241+ ?keywords:string list ->
242242+ ?license:Cff_license.t ->
243243+ ?license_url:string ->
244244+ ?preferred_citation:Cff_reference.t ->
245245+ ?references:Cff_reference.t list ->
246246+ ?repository:string ->
247247+ ?repository_artifact:string ->
248248+ ?repository_code:string ->
249249+ ?type_:Cff_enums.Cff_type.t ->
250250+ ?url:string ->
251251+ ?version:string ->
252252+ unit -> t
253253+(** [make ~title ~authors ...] constructs a CFF value.
254254+255255+ @param cff_version The CFF schema version (default: {!default_cff_version})
256256+ @param message Instructions for users on how to cite (default: {!default_message})
257257+ @param title The name of the software or dataset
258258+ @param authors List of persons and/or entities who created the work *)
259259+260260+(** {1 Required Fields} *)
261261+262262+val cff_version : t -> string
263263+(** The CFF schema version that this file adheres to.
264264+265265+ For CFF 1.2.0 files, this should be ["1.2.0"]. The version determines
266266+ which keys are valid and how they should be interpreted. *)
267267+268268+val message : t -> string
269269+(** A message to readers explaining how to cite the work.
270270+271271+ Common examples:
272272+ - ["If you use this software, please cite it using the metadata from this file."]
273273+ - ["Please cite this software using the metadata from 'preferred-citation'."]
274274+275275+ The message should guide users toward the preferred citation method. *)
276276+277277+val title : t -> string
278278+(** The name of the software or dataset.
193279194194-include module type of Cff_root
280280+ This is the title that should appear in citations. For software, it's
281281+ typically the project name; for datasets, the dataset title. *)
282282+283283+val authors : t -> Cff_author.t list
284284+(** The creators of the software or dataset.
285285+286286+ Authors can be persons (individuals) or entities (organizations).
287287+ At least one author is required for a valid CFF file. The order
288288+ typically reflects contribution significance. *)
289289+290290+(** {1 Optional Fields} *)
291291+292292+val abstract : t -> string option
293293+(** A description of the software or dataset.
294294+295295+ Provides context about what the work does, its purpose, and scope. *)
296296+297297+val commit : t -> string option
298298+(** The commit hash or revision number of the software version.
299299+300300+ Useful for precise version identification beyond semantic versioning.
301301+ Example: ["1ff847d81f29c45a3a1a5ce73d38e45c2f319bba"] *)
302302+303303+val contact : t -> Cff_author.t list option
304304+(** Contact persons or entities for the software or dataset.
305305+306306+ May differ from authors; useful when the primary contact is a
307307+ project maintainer rather than the original author. *)
308308+309309+val date_released : t -> Cff_date.t option
310310+(** The date when the software or dataset was released.
311311+312312+ Format is [(year, month, day)], corresponding to ISO 8601 [YYYY-MM-DD]. *)
313313+314314+val doi : t -> string option
315315+(** The Digital Object Identifier for the software or dataset.
316316+317317+ DOIs provide persistent, citable identifiers. This is a shorthand
318318+ for a single DOI; use {!identifiers} for multiple DOIs or other
319319+ identifier types. Example: ["10.5281/zenodo.1234567"] *)
320320+321321+val identifiers : t -> Cff_identifier.t list option
322322+(** Additional identifiers beyond the primary DOI.
323323+324324+ Each identifier has a type (DOI, URL, SWH, other), value, and
325325+ optional description. Useful for versioned DOIs, Software Heritage
326326+ identifiers, or repository URLs. *)
327327+328328+val keywords : t -> string list option
329329+(** Descriptive keywords for the work.
330330+331331+ Help with discoverability and categorization. Example:
332332+ [["machine learning"; "image processing"; "python"]] *)
333333+334334+val license : t -> Cff_license.t option
335335+(** The SPDX license identifier(s) for the work.
336336+337337+ Uses {{:https://spdx.org/licenses/}SPDX identifiers}. Multiple
338338+ licenses imply an OR relationship (user may choose any).
339339+ Example: ["MIT"], ["Apache-2.0"], or [["GPL-3.0-only"; "MIT"]]. *)
340340+341341+val license_url : t -> string option
342342+(** URL to the license text for non-standard licenses.
343343+344344+ Only needed for licenses not in the SPDX list. Standard SPDX
345345+ licenses have well-known URLs. *)
346346+347347+val preferred_citation : t -> Cff_reference.t option
348348+(** A reference to cite instead of the software itself.
349349+350350+ Used for "credit redirection" when authors prefer citation of
351351+ a related publication (e.g., a methods paper) over the software.
352352+ Note: Software citation principles recommend citing software
353353+ directly; use this field judiciously. *)
354354+355355+val references : t -> Cff_reference.t list option
356356+(** Works that this software cites or depends upon.
357357+358358+ Functions like a bibliography, listing dependencies, foundational
359359+ works, or related publications. Each reference includes full
360360+ bibliographic metadata. *)
361361+362362+val repository : t -> string option
363363+(** URL to the repository where the software is developed.
364364+365365+ Typically a version control system URL. For source code repositories,
366366+ prefer {!repository_code}. *)
367367+368368+val repository_artifact : t -> string option
369369+(** URL to the built/compiled artifact repository.
370370+371371+ For binary distributions, package registries (npm, PyPI, CRAN),
372372+ or container registries. *)
373373+374374+val repository_code : t -> string option
375375+(** URL to the source code repository.
376376+377377+ Typically a GitHub, GitLab, or similar URL where the source
378378+ code is publicly accessible. *)
379379+380380+val type_ : t -> Cff_enums.Cff_type.t option
381381+(** The type of work: [`Software] (default) or [`Dataset].
382382+383383+ Most CFF files describe software; use [`Dataset] for data packages. *)
384384+385385+val url : t -> string option
386386+(** The URL of the software or dataset homepage.
387387+388388+ A general landing page, documentation site, or project website. *)
389389+390390+val version : t -> string option
391391+(** The version string of the software or dataset.
392392+393393+ Can be any version format: semantic versioning (["1.2.3"]),
394394+ date-based (["2024.01"]), or other schemes. *)
395395+396396+(** {1 Formatting and Codec} *)
397397+398398+val pp : Format.formatter -> t -> unit
399399+(** Pretty-print a CFF value in a human-readable YAML-like format. *)
400400+401401+val jsont : t Jsont.t
402402+(** JSON/YAML codec for serialization and deserialization.
403403+404404+ Used internally by the YAML codec functions. *)
-175
lib/cff_root.ml
···11-(*---------------------------------------------------------------------------
22- Copyright (c) 2025 The ocaml-cff programmers. All rights reserved.
33- SPDX-License-Identifier: ISC
44- ---------------------------------------------------------------------------*)
55-66-(** Root CFF type. *)
77-88-type t = {
99- cff_version : string;
1010- message : string;
1111- title : string;
1212- authors : Cff_author.t list;
1313- abstract : string option;
1414- commit : string option;
1515- contact : Cff_author.t list option;
1616- date_released : Cff_date.t option;
1717- doi : string option;
1818- identifiers : Cff_identifier.t list option;
1919- keywords : string list option;
2020- license : Cff_license.t option;
2121- license_url : string option;
2222- preferred_citation : Cff_reference.t option;
2323- references : Cff_reference.t list option;
2424- repository : string option;
2525- repository_artifact : string option;
2626- repository_code : string option;
2727- type_ : Cff_enums.Cff_type.t option;
2828- url : string option;
2929- version : string option;
3030-}
3131-3232-let make
3333- ~cff_version
3434- ~message
3535- ~title
3636- ~authors
3737- ?abstract
3838- ?commit
3939- ?contact
4040- ?date_released
4141- ?doi
4242- ?identifiers
4343- ?keywords
4444- ?license
4545- ?license_url
4646- ?preferred_citation
4747- ?references
4848- ?repository
4949- ?repository_artifact
5050- ?repository_code
5151- ?type_
5252- ?url
5353- ?version
5454- () =
5555- { cff_version; message; title; authors;
5656- abstract; commit; contact; date_released; doi;
5757- identifiers; keywords; license; license_url;
5858- preferred_citation; references; repository;
5959- repository_artifact; repository_code; type_; url; version }
6060-6161-(* Required field accessors *)
6262-let cff_version t = t.cff_version
6363-let message t = t.message
6464-let title t = t.title
6565-let authors t = t.authors
6666-6767-(* Optional field accessors *)
6868-let abstract t = t.abstract
6969-let commit t = t.commit
7070-let contact t = t.contact
7171-let date_released t = t.date_released
7272-let doi t = t.doi
7373-let identifiers t = t.identifiers
7474-let keywords t = t.keywords
7575-let license t = t.license
7676-let license_url t = t.license_url
7777-let preferred_citation t = t.preferred_citation
7878-let references t = t.references
7979-let repository t = t.repository
8080-let repository_artifact t = t.repository_artifact
8181-let repository_code t = t.repository_code
8282-let type_ t = t.type_
8383-let url t = t.url
8484-let version t = t.version
8585-8686-let make_simple ~title ~authors ?version ?doi ?license () =
8787- let message = "If you use this software, please cite it using the metadata from this file." in
8888- make
8989- ~cff_version:"1.2.0"
9090- ~message
9191- ~title
9292- ~authors
9393- ?version
9494- ?doi
9595- ?license
9696- ()
9797-9898-let pp ppf t =
9999- Format.fprintf ppf "@[<v>";
100100- Format.fprintf ppf "cff-version: %s@," t.cff_version;
101101- Format.fprintf ppf "title: %s@," t.title;
102102- Format.fprintf ppf "message: %s@," t.message;
103103- Format.fprintf ppf "authors:@,";
104104- List.iter (fun a -> Format.fprintf ppf " - %a@," Cff_author.pp a) t.authors;
105105- Option.iter (fun v -> Format.fprintf ppf "version: %s@," v) t.version;
106106- Option.iter (fun v -> Format.fprintf ppf "doi: %s@," v) t.doi;
107107- Option.iter (fun v -> Format.fprintf ppf "date-released: %a@," Cff_date.pp v) t.date_released;
108108- Option.iter (fun v -> Format.fprintf ppf "license: %a@," Cff_license.pp v) t.license;
109109- Option.iter (fun v -> Format.fprintf ppf "url: %s@," v) t.url;
110110- Option.iter (fun v -> Format.fprintf ppf "repository: %s@," v) t.repository;
111111- Option.iter (fun v -> Format.fprintf ppf "repository-code: %s@," v) t.repository_code;
112112- Option.iter (fun v -> Format.fprintf ppf "abstract: %s@," v) t.abstract;
113113- Option.iter (fun v -> Format.fprintf ppf "commit: %s@," v) t.commit;
114114- Option.iter (fun v -> Format.fprintf ppf "type: %a@," Cff_enums.Cff_type.pp v) t.type_;
115115- Option.iter (fun kws ->
116116- Format.fprintf ppf "keywords:@,";
117117- List.iter (fun k -> Format.fprintf ppf " - %s@," k) kws
118118- ) t.keywords;
119119- Option.iter (fun ids ->
120120- Format.fprintf ppf "identifiers:@,";
121121- List.iter (fun id -> Format.fprintf ppf " - %a@," Cff_identifier.pp id) ids
122122- ) t.identifiers;
123123- Option.iter (fun contacts ->
124124- Format.fprintf ppf "contact:@,";
125125- List.iter (fun c -> Format.fprintf ppf " - %a@," Cff_author.pp c) contacts
126126- ) t.contact;
127127- Option.iter (fun refs ->
128128- Format.fprintf ppf "references:@,";
129129- List.iter (fun r -> Format.fprintf ppf " - %a@," Cff_reference.pp r) refs
130130- ) t.references;
131131- Option.iter (fun pc ->
132132- Format.fprintf ppf "preferred-citation:@, %a@," Cff_reference.pp pc
133133- ) t.preferred_citation;
134134- Format.fprintf ppf "@]"
135135-136136-let list_jsont elt = Jsont.(array elt |> map ~dec:Stdlib.Array.to_list ~enc:Stdlib.Array.of_list)
137137-138138-let jsont =
139139- let open Jsont in
140140- let authors_jsont = list_jsont Cff_author.jsont in
141141- let identifiers_jsont = list_jsont Cff_identifier.jsont in
142142- let references_jsont = list_jsont Cff_reference.jsont in
143143- let keywords_jsont = list_jsont string in
144144- Object.map ~kind:"CFF"
145145- (fun cff_version message title authors abstract commit contact
146146- date_released doi identifiers keywords license license_url
147147- preferred_citation references repository repository_artifact
148148- repository_code type_ url version ->
149149- { cff_version; message; title; authors;
150150- abstract; commit; contact; date_released; doi;
151151- identifiers; keywords; license; license_url;
152152- preferred_citation; references; repository;
153153- repository_artifact; repository_code; type_; url; version })
154154- |> Object.mem "cff-version" string ~enc:(fun t -> t.cff_version)
155155- |> Object.mem "message" string ~enc:(fun t -> t.message)
156156- |> Object.mem "title" string ~enc:(fun t -> t.title)
157157- |> Object.mem "authors" authors_jsont ~enc:(fun t -> t.authors)
158158- |> Object.opt_mem "abstract" string ~enc:(fun t -> t.abstract)
159159- |> Object.opt_mem "commit" string ~enc:(fun t -> t.commit)
160160- |> Object.opt_mem "contact" authors_jsont ~enc:(fun t -> t.contact)
161161- |> Object.opt_mem "date-released" Cff_date.jsont ~enc:(fun t -> t.date_released)
162162- |> Object.opt_mem "doi" string ~enc:(fun t -> t.doi)
163163- |> Object.opt_mem "identifiers" identifiers_jsont ~enc:(fun t -> t.identifiers)
164164- |> Object.opt_mem "keywords" keywords_jsont ~enc:(fun t -> t.keywords)
165165- |> Object.opt_mem "license" Cff_license.jsont_lenient ~enc:(fun t -> t.license)
166166- |> Object.opt_mem "license-url" string ~enc:(fun t -> t.license_url)
167167- |> Object.opt_mem "preferred-citation" Cff_reference.jsont ~enc:(fun t -> t.preferred_citation)
168168- |> Object.opt_mem "references" references_jsont ~enc:(fun t -> t.references)
169169- |> Object.opt_mem "repository" string ~enc:(fun t -> t.repository)
170170- |> Object.opt_mem "repository-artifact" string ~enc:(fun t -> t.repository_artifact)
171171- |> Object.opt_mem "repository-code" string ~enc:(fun t -> t.repository_code)
172172- |> Object.opt_mem "type" Cff_enums.Cff_type.jsont ~enc:(fun t -> t.type_)
173173- |> Object.opt_mem "url" string ~enc:(fun t -> t.url)
174174- |> Object.opt_mem "version" string ~enc:(fun t -> t.version)
175175- |> Object.finish
-249
lib/cff_root.mli
···11-(*---------------------------------------------------------------------------
22- Copyright (c) 2025 The ocaml-cff programmers. All rights reserved.
33- SPDX-License-Identifier: ISC
44- ---------------------------------------------------------------------------*)
55-66-(** Root CFF type representing a complete [CITATION.cff] file.
77-88- A [CITATION.cff] file is the standard way to provide citation metadata
99- for research software and datasets. This module defines the root type
1010- containing all top-level fields from the CFF 1.2.0 specification.
1111-1212- {2 Required Fields}
1313-1414- Every valid CFF file must include:
1515- - {!cff_version}: Schema version (["1.2.0"])
1616- - {!message}: Instructions for citing the work
1717- - {!title}: Name of the software or dataset
1818- - {!authors}: List of persons and/or entities
1919-2020- {2 Common Optional Fields}
2121-2222- - {!version}: Software version string
2323- - {!doi}: Digital Object Identifier
2424- - {!date_released}: Publication/release date
2525- - {!license}: SPDX license identifier(s)
2626- - {!keywords}: Descriptive keywords
2727- - {!abstract}: Description of the work
2828-2929- {2 Citation Redirection}
3030-3131- The {!preferred_citation} field allows redirecting citations to
3232- a related work (e.g., a journal article describing the software).
3333- The {!references} field lists works that the software cites or
3434- depends upon.
3535-3636- {2 Example}
3737-3838- {[
3939- let cff = Cff_root.make
4040- ~cff_version:"1.2.0"
4141- ~message:"If you use this software, please cite it as below."
4242- ~title:"My Research Software"
4343- ~authors:[Cff_author.Person (Cff_author.Person.make
4444- ~family_names:"Smith"
4545- ~given_names:"Jane"
4646- ())]
4747- ~version:"1.0.0"
4848- ~doi:"10.5281/zenodo.1234567"
4949- ~date_released:(2024, 1, 15)
5050- ~license:(Cff_license.single "MIT")
5151- ()
5252- ]} *)
5353-5454-(** The abstract type representing a complete CFF document. *)
5555-type t
5656-5757-(** {1 Construction} *)
5858-5959-val make :
6060- cff_version:string ->
6161- message:string ->
6262- title:string ->
6363- authors:Cff_author.t list ->
6464- ?abstract:string ->
6565- ?commit:string ->
6666- ?contact:Cff_author.t list ->
6767- ?date_released:Cff_date.t ->
6868- ?doi:string ->
6969- ?identifiers:Cff_identifier.t list ->
7070- ?keywords:string list ->
7171- ?license:Cff_license.t ->
7272- ?license_url:string ->
7373- ?preferred_citation:Cff_reference.t ->
7474- ?references:Cff_reference.t list ->
7575- ?repository:string ->
7676- ?repository_artifact:string ->
7777- ?repository_code:string ->
7878- ?type_:Cff_enums.Cff_type.t ->
7979- ?url:string ->
8080- ?version:string ->
8181- unit -> t
8282-(** [make ~cff_version ~message ~title ~authors ...] constructs a CFF value.
8383-8484- @param cff_version The CFF schema version, typically ["1.2.0"]
8585- @param message Instructions for users on how to cite the work
8686- @param title The name of the software or dataset
8787- @param authors List of persons and/or entities who created the work *)
8888-8989-(** {1 Required Fields} *)
9090-9191-val cff_version : t -> string
9292-(** The CFF schema version that this file adheres to.
9393-9494- For CFF 1.2.0 files, this should be ["1.2.0"]. The version determines
9595- which keys are valid and how they should be interpreted. *)
9696-9797-val message : t -> string
9898-(** A message to readers explaining how to cite the work.
9999-100100- Common examples:
101101- - ["If you use this software, please cite it using the metadata from this file."]
102102- - ["Please cite this software using the metadata from 'preferred-citation'."]
103103-104104- The message should guide users toward the preferred citation method. *)
105105-106106-val title : t -> string
107107-(** The name of the software or dataset.
108108-109109- This is the title that should appear in citations. For software, it's
110110- typically the project name; for datasets, the dataset title. *)
111111-112112-val authors : t -> Cff_author.t list
113113-(** The creators of the software or dataset.
114114-115115- Authors can be persons (individuals) or entities (organizations).
116116- At least one author is required for a valid CFF file. The order
117117- typically reflects contribution significance. *)
118118-119119-(** {1 Optional Fields} *)
120120-121121-val abstract : t -> string option
122122-(** A description of the software or dataset.
123123-124124- Provides context about what the work does, its purpose, and scope. *)
125125-126126-val commit : t -> string option
127127-(** The commit hash or revision number of the software version.
128128-129129- Useful for precise version identification beyond semantic versioning.
130130- Example: ["1ff847d81f29c45a3a1a5ce73d38e45c2f319bba"] *)
131131-132132-val contact : t -> Cff_author.t list option
133133-(** Contact persons or entities for the software or dataset.
134134-135135- May differ from authors; useful when the primary contact is a
136136- project maintainer rather than the original author. *)
137137-138138-val date_released : t -> Cff_date.t option
139139-(** The date when the software or dataset was released.
140140-141141- Format is [(year, month, day)], corresponding to ISO 8601 [YYYY-MM-DD]. *)
142142-143143-val doi : t -> string option
144144-(** The Digital Object Identifier for the software or dataset.
145145-146146- DOIs provide persistent, citable identifiers. This is a shorthand
147147- for a single DOI; use {!identifiers} for multiple DOIs or other
148148- identifier types. Example: ["10.5281/zenodo.1234567"] *)
149149-150150-val identifiers : t -> Cff_identifier.t list option
151151-(** Additional identifiers beyond the primary DOI.
152152-153153- Each identifier has a type (DOI, URL, SWH, other), value, and
154154- optional description. Useful for versioned DOIs, Software Heritage
155155- identifiers, or repository URLs. *)
156156-157157-val keywords : t -> string list option
158158-(** Descriptive keywords for the work.
159159-160160- Help with discoverability and categorization. Example:
161161- [["machine learning"; "image processing"; "python"]] *)
162162-163163-val license : t -> Cff_license.t option
164164-(** The SPDX license identifier(s) for the work.
165165-166166- Uses {{:https://spdx.org/licenses/}SPDX identifiers}. Multiple
167167- licenses imply an OR relationship (user may choose any).
168168- Example: ["MIT"], ["Apache-2.0"], or [["GPL-3.0-only"; "MIT"]]. *)
169169-170170-val license_url : t -> string option
171171-(** URL to the license text for non-standard licenses.
172172-173173- Only needed for licenses not in the SPDX list. Standard SPDX
174174- licenses have well-known URLs. *)
175175-176176-val preferred_citation : t -> Cff_reference.t option
177177-(** A reference to cite instead of the software itself.
178178-179179- Used for "credit redirection" when authors prefer citation of
180180- a related publication (e.g., a methods paper) over the software.
181181- Note: Software citation principles recommend citing software
182182- directly; use this field judiciously. *)
183183-184184-val references : t -> Cff_reference.t list option
185185-(** Works that this software cites or depends upon.
186186-187187- Functions like a bibliography, listing dependencies, foundational
188188- works, or related publications. Each reference includes full
189189- bibliographic metadata. *)
190190-191191-val repository : t -> string option
192192-(** URL to the repository where the software is developed.
193193-194194- Typically a version control system URL. For source code repositories,
195195- prefer {!repository_code}. *)
196196-197197-val repository_artifact : t -> string option
198198-(** URL to the built/compiled artifact repository.
199199-200200- For binary distributions, package registries (npm, PyPI, CRAN),
201201- or container registries. *)
202202-203203-val repository_code : t -> string option
204204-(** URL to the source code repository.
205205-206206- Typically a GitHub, GitLab, or similar URL where the source
207207- code is publicly accessible. *)
208208-209209-val type_ : t -> Cff_enums.Cff_type.t option
210210-(** The type of work: [`Software] (default) or [`Dataset].
211211-212212- Most CFF files describe software; use [`Dataset] for data packages. *)
213213-214214-val url : t -> string option
215215-(** The URL of the software or dataset homepage.
216216-217217- A general landing page, documentation site, or project website. *)
218218-219219-val version : t -> string option
220220-(** The version string of the software or dataset.
221221-222222- Can be any version format: semantic versioning (["1.2.3"]),
223223- date-based (["2024.01"]), or other schemes. *)
224224-225225-(** {1 Convenience Constructors} *)
226226-227227-val make_simple :
228228- title:string ->
229229- authors:Cff_author.t list ->
230230- ?version:string ->
231231- ?doi:string ->
232232- ?license:Cff_license.t ->
233233- unit -> t
234234-(** Create a minimal CFF with sensible defaults.
235235-236236- Uses [cff_version = "1.2.0"] and the standard message:
237237- ["If you use this software, please cite it using the metadata from this file."]
238238-239239- This is the quickest way to create a valid CFF for simple projects. *)
240240-241241-(** {1 Formatting and Codec} *)
242242-243243-val pp : Format.formatter -> t -> unit
244244-(** Pretty-print a CFF value in a human-readable YAML-like format. *)
245245-246246-val jsont : t Jsont.t
247247-(** JSON/YAML codec for serialization and deserialization.
248248-249249- Used internally by the YAML codec functions. *)
+1-1
test/test_cff.ml
···5353let test_create_programmatic () =
5454 let author = Cff.Author.Person
5555 (Cff.Person.make ~family_names:"Smith" ~given_names:"Jane" ()) in
5656- let cff = Cff.make_simple
5656+ let cff = Cff.make
5757 ~title:"My Software"
5858 ~authors:[author]
5959 ~version:"1.0.0"