1 | type t = {
|
---|
2 | meta: Meta.t;
|
---|
3 | body: string;
|
---|
4 | } [@@deriving lens { submodule = true }]
|
---|
5 |
|
---|
6 | let blank ?(uuid=(Meta.Id.generate ())) () = { meta = Meta.blank ~uuid (); body = "" }
|
---|
7 |
|
---|
8 | let title ymd =
|
---|
9 | let mtitle = ymd.meta.Meta.title in
|
---|
10 | if String.length mtitle > 0 then mtitle else
|
---|
11 | let open Omd in
|
---|
12 | try List.find (function H1 _ -> true | _ -> false) (Omd.of_string ymd.body)
|
---|
13 | |> function H1 h -> to_text h | _ -> ""
|
---|
14 | with Not_found -> ""
|
---|
15 |
|
---|
16 | let categorised categs ymd = Meta.CategorySet.categorised categs ymd.meta.Meta.categories
|
---|
17 |
|
---|
18 | let with_kv ymd (k,v) = match k with
|
---|
19 | | "body" -> { ymd with body = String.trim v }
|
---|
20 | | _ -> { ymd with meta = Meta.with_kv ymd.meta (k,v) }
|
---|
21 |
|
---|
22 | let meta_pair_of_string line = match Re.Str.(bounded_split (regexp ": *")) line 2 with
|
---|
23 | | [ key; value ] -> Re.Str.(replace_first (regexp "^#\\+") "" key), value
|
---|
24 | | [ key ] -> Re.Str.(replace_first (regexp "^#\\+") "" key), ""
|
---|
25 | | _ -> prerr_endline line; ("","")
|
---|
26 |
|
---|
27 | let meta_of_string front_matter =
|
---|
28 | let fields = List.map meta_pair_of_string (String.split_on_char '\n' front_matter) in
|
---|
29 | List.fold_left Meta.with_kv (Meta.blank ()) fields
|
---|
30 |
|
---|
31 | exception Syntax_error of string
|
---|
32 |
|
---|
33 | let front_matter_body_split s =
|
---|
34 | if Re.Str.(string_match (regexp ".*:.*")) s 0
|
---|
35 | then match Re.Str.(bounded_split (regexp "\n\n")) s 2 with
|
---|
36 | | front::body::[] -> (front, body)
|
---|
37 | | _ -> ("", s)
|
---|
38 | else ("", s)
|
---|
39 |
|
---|
40 | let of_string s =
|
---|
41 | let (front_matter, body) = front_matter_body_split s in
|
---|
42 | try
|
---|
43 | let note = { meta = meta_of_string front_matter; body } in
|
---|
44 | { note with meta = { note.meta with title = title note } }
|
---|
45 | with _ -> prerr_endline ("Failed parsing" ^ s); blank ()
|
---|
46 |
|
---|
47 | let to_string ymd = Meta.to_string ymd.meta ^ "\n" ^ ymd.body
|
---|