module type Fn = sig type t val reference_name: string -> string -> t -> t val referent_s: string -> t -> t val referent_e: t -> t end open Text_parse.Parser open Text_parse.Cursor open Text_parse.Syntax module Name (F : Fn) = struct type t = F.t let s _cursor = function '[' -> true | _ -> false let e _cursor = function ']' -> true | _ -> false let parse cur acc = F.reference_name (segment_string (unwrap 1 cur)) acc end module Referent (F : Fn) = struct type t = F.t let find_name_end = find_end (fun cur c -> c = ']' && (char_at cur 1) = ':') let s cur = function '[' -> Option.is_some (find_name_end cur) | _ -> false let e _cur = newline let subsyntaxes = [| |] let parse cur acc = let name_boundary = match find_name_end cur with Some x -> x | None -> 0 in let name = segment_string { cur with pos = cur.pos+1; right_boundary = name_boundary-1 } in let text_cur = { cur with pos = name_boundary+2 } in F.referent_s name acc |> parse subsyntaxes text_cur |> F.referent_e end