(*--------------------------------------------------------------------------- Copyright (c) 2026 The ocaml-cff programmers. All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) (** Authors for CFF: persons and entities. CFF distinguishes between two types of authors: - {b Persons}: Individual humans identified by name components (family names, given names, etc.) - {b Entities}: Organizations, institutions, teams, projects, or conferences identified by a single [name] field When parsing YAML, the library discriminates based on the presence of a [name] field: if present, the entry is an entity; otherwise, it's a person. {1 Quick Example} {[ (* Create a person author *) let jane = Cff.Author.person ~family_names:"Smith" ~given_names:"Jane" ~affiliation:"MIT" () (* Create an entity author *) let mozilla = Cff.Author.entity ~name:"Mozilla Foundation" () (* Pattern match on authors *) let show_author = function | `Person p -> Cff.Author.Person.full_name p | `Entity e -> Cff.Author.Entity.name e ]} *) (** {1 Person} Individual person (author, contributor, editor, etc.). A person represents a human contributor with: - Name components (family names, given names, particle, suffix, alias) - Optional affiliation (institution, company) - Optional physical address - Optional contact information (email, ORCID, website) *) module Person : sig (** A person record. *) type t (** Create a person with optional fields. At minimum, provide [family_names] or [given_names]. @param family_names Last name/surname @param given_names First name(s) @param name_particle Connector before family name (e.g., "von", "van") @param name_suffix Generational suffix (e.g., "Jr.", "III") @param alias Nickname or pseudonym @param affiliation Institution or organization name @param address Physical address @param contact Contact information (email, ORCID, website, etc.) *) val make : ?family_names:string -> ?given_names:string -> ?name_particle:string -> ?name_suffix:string -> ?alias:string -> ?affiliation:string -> ?address:Cff_address.Address.t -> ?contact:Cff_address.Contact.t -> unit -> t (** {2 Name Fields} *) (** The person's family name (surname, last name). *) val family_names : t -> string option (** The person's given name(s) (first name, forenames). *) val given_names : t -> string option (** Name connector appearing before family name. Examples: ["von"] in "Ludwig von Beethoven". *) val name_particle : t -> string option (** Generational or honorary suffix. Examples: ["Jr."], ["Sr."], ["III"]. *) val name_suffix : t -> string option (** Nickname, pseudonym, or alternative name. *) val alias : t -> string option (** Format name as "Given Particle Family, Suffix". Examples: ["Jane Smith"], ["Guido van Rossum"]. *) val full_name : t -> string (** {2 Affiliation and Location} *) (** The person's institutional affiliation. *) val affiliation : t -> string option (** Physical address information. *) val address : t -> Cff_address.Address.t (** {2 Contact Information} *) (** Full contact information record. *) val contact : t -> Cff_address.Contact.t (** The person's email address. *) val email : t -> string option (** The person's ORCID identifier URL. *) val orcid : t -> string option (** The person's website URL. *) val website : t -> string option (** {2 Formatting and Codec} *) (** Pretty-print as "Full Name (affiliation)". *) val pp : Format.formatter -> t -> unit (** JSON/YAML codec for person records. *) val jsont : t Jsont.t end (** {1 Entity} Organization, institution, project, or conference. An entity represents a non-person author or contributor, such as: - Research institutions (["MIT"], ["CERN"]) - Companies (["Google"], ["Mozilla Foundation"]) - Open source projects (["The Rust Project"]) - Academic conferences (["ICSE 2024"]) with dates Entities are distinguished from persons in YAML by the presence of a required [name] field. *) module Entity : sig (** An entity record. *) type t (** Create an entity. @param name The entity's official name (required) @param alias Short name or acronym @param address Physical address @param contact Contact information (email, website, etc.) @param date_start Event start date (for conferences) @param date_end Event end date (for conferences) @param location Event location description *) val make : name:string -> ?alias:string -> ?address:Cff_address.Address.t -> ?contact:Cff_address.Contact.t -> ?date_start:Cff_date.t -> ?date_end:Cff_date.t -> ?location:string -> unit -> t (** {2 Core Fields} *) (** The entity's official name. *) val name : t -> string (** Short name, acronym, or alternative name. *) val alias : t -> string option (** {2 Location} *) (** Physical address information. *) val address : t -> Cff_address.Address.t (** Event location description (for conferences). *) val location : t -> string option (** {2 Event Dates} *) (** The start date of the event (for conferences). *) val date_start : t -> Cff_date.t option (** The end date of the event (for conferences). *) val date_end : t -> Cff_date.t option (** {2 Contact Information} *) (** Full contact information record. *) val contact : t -> Cff_address.Contact.t (** The entity's contact email. *) val email : t -> string option (** The entity's ORCID (organizations can have ORCIDs). *) val orcid : t -> string option (** The entity's official website URL. *) val website : t -> string option (** {2 Formatting and Codec} *) (** Pretty-print as "Name (alias)". *) val pp : Format.formatter -> t -> unit (** JSON/YAML codec for entity records. *) val jsont : t Jsont.t end (** {1 Author Type} The main author type is a polymorphic variant that can hold either a person or an entity. *) (** An author: either a person or an entity. *) type t = [ `Person of Person.t | `Entity of Entity.t ] (** {2 Smart Constructors} *) (** Create a person author directly. Equivalent to [`Person (Person.make ...)]. *) val person : ?family_names:string -> ?given_names:string -> ?name_particle:string -> ?name_suffix:string -> ?alias:string -> ?affiliation:string -> ?address:Cff_address.Address.t -> ?contact:Cff_address.Contact.t -> unit -> t (** Create an entity author directly. Equivalent to [`Entity (Entity.make ...)]. *) val entity : name:string -> ?alias:string -> ?address:Cff_address.Address.t -> ?contact:Cff_address.Contact.t -> ?date_start:Cff_date.t -> ?date_end:Cff_date.t -> ?location:string -> unit -> t (** {2 Common Accessors} *) (** Get the display name. For persons, returns the full formatted name. For entities, returns the entity name. *) val name : t -> string (** Get the ORCID if present. Works for both persons and entities. *) val orcid : t -> string option (** Get the email if present. Works for both persons and entities. *) val email : t -> string option (** {2 Formatting and Codec} *) (** Pretty-print the author. *) val pp : Format.formatter -> t -> unit (** JSON/YAML codec that discriminates based on [name] field presence. When decoding: - If the object has a [name] field -> Entity - Otherwise -> Person *) val jsont : t Jsont.t