(* SPDX-License-Identifier: AGPL-3.0-or-later *) (** Turn a parsed citation back into text, in a configurable style. A style is data, not code, so a tradition of punctuation is a file someone can write: [Luke 5:12-14], [Lk 5:12-14], [Luke 5.12-14], [{L}k 5, 12-14] are all the same citation in different conventions. Placeholders: [{chapter}], [{chapter_roman}] and [{verses}] in [chapter_verse]; [{first}] and [{last}] in [range]. An UNKNOWN placeholder survives literally, so a typo is visible in the output rather than silently swallowed. *) type style (** The Vulgate/Latin convention: abbreviated book, [chapter:verses], [first-last], ["; "] between parts, [", "] between verse ranges. *) val default_style : style (** Read a style from a language file's [\[sigla\]] section. Values are UNQUOTED here: one matching pair of surrounding double quotes is stripped, so a separator's significant trailing space survives. {!Colitur_kernel.Overlay_ini} trims every value and has no quote handling, and it is shared with overlays and [\[defaults\]] -- so the unquoting belongs here, not there. An unrecognised key is ignored; a missing key keeps {!default_style}'s value. *) val style_of_fields : (string * string) list -> style (** Override the book form, for the [sigla_book] config key. *) val with_book : [ `Full | `Abbr ] -> style -> style val part_sep : style -> string val range : style -> string (** What separates the book name from the reference. Default [" "]. Settable because a typeset booklet wants a NON-BREAKING space here -- a line break between "Luc." and "3, 1" is exactly the ugliness this prevents. Set it to a literal U+00A0: the escapers match ASCII bytes only, so a UTF-8 multibyte sequence passes through every flavour untouched (verified for latex, typst, groff, html, xml, ics). A LaTeX tie [~] does NOT work -- {!Colitur_render.Escape} turns it into [\textasciitilde{}]. *) val book_sep : style -> string (** The style's own book form, as the string a config file would write (["full"] or ["abbr"]). Exists so a caller can use the STYLE's value as the default when resolving the [sigla_book] setting. Resolving against a hardcoded ["abbr"] instead makes a style file's own [book] key unreachable -- the value is always overwritten before it can apply -- which is what shipped until this accessor existed. *) val book_string : style -> string val render : style -> names:(Book.id -> [ `Full | `Abbr ] -> string) -> Parse.t -> string