From 56e36188c6afc208b96b15b9a1d3d62bbbe2f705 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 20 Aug 2026 14:59:03 +0200 Subject: feat(citation): parse citations into structure The parsed form is a book and a LIST of chapter-parts: the data cites across chapters and lists disjoint verse ranges within one. Two rules the shipped data forces and that are not obvious: a semicolon-separated part may inherit the previous chapter rather than restate it, and a chapter may be separated from its verses by a comma. --- lib/citation/parse.mli | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 lib/citation/parse.mli (limited to 'lib/citation/parse.mli') diff --git a/lib/citation/parse.mli b/lib/citation/parse.mli new file mode 100644 index 0000000..3d1053c --- /dev/null +++ b/lib/citation/parse.mli @@ -0,0 +1,15 @@ +(* SPDX-License-Identifier: AGPL-3.0-or-later *) + +(** A citation, parsed. Never raises; an unrecognised string is an [Error] + naming what could not be read, never a silent pass-through. + + The shape is a book and a LIST of chapter-parts, not one chapter and one + verse range, because the shipped data really does cite across chapters + ([John 18:1-40; 19:1-42]) and really does list disjoint verse ranges + within a chapter ([Dan 13:1-9, 15-17, 19-30, 33-62]). *) + +type verse_range = { first : int; last : int option } +type part = { chapter : int; verses : verse_range list } +type t = { book : Book.id; parts : part list } + +val parse : string -> (t, string) result -- cgit v1.3