1 | open Core |
2 | |
3 | let pattern = Re.Pcre.regexp {|(.*)?note-(\d{8})-(\d{1,})(.md)?|} |
4 | |
5 | type t = { path : string; date : Date.t; index : int } |
6 | |
7 | let to_string slug = slug.path |
8 | |
9 | let of_string ?(basepath = None) path = |
10 | let result = Re.all pattern path |> List.hd_exn in |
11 | let items = Re.Group.all result |> Array.to_list in |
12 | let date = Date_unix.parse ~fmt:"%Y%m%d" (List.nth_exn items 2) in |
13 | let index = int_of_string (List.nth_exn items 3) in |
14 | let path = |
15 | match basepath with |
16 | | Some basepath -> Filename.concat basepath path |
17 | | None -> path |
18 | in |
19 | let path = |
20 | match Filename.check_suffix path "md" with |
21 | | true -> path |
22 | | false -> String.concat [ path; ".md" ] |
23 | in |
24 | { path; date; index } |
25 | |
26 | let shortname t = |
27 | let date_str = Date_unix.format t.date "%Y%m%d" in |
28 | sprintf "note-%s-%d" date_str t.index |
29 | |
30 | let append ~path t = |
31 | let path = Filename.concat path t.path in |
32 | { t with path } |
33 | |
34 | let compare s1 s2 = String.compare s1.path s2.path |
35 | |
36 | let is_note path = |
37 | Filename.basename path |> String.is_substring ~substring:"note-" |
38 | |
39 | let load state_dir = |
40 | state_dir |> Sys_unix.ls_dir |> List.filter ~f:is_note |
41 | |> List.map ~f:(Filename.concat state_dir) |
42 | |> List.map ~f:of_string |
43 | |
44 | let next ?(last = None) state_dir = |
45 | let today = Time_float_unix.now () |> Time_float_unix.to_date ~zone:Time_float_unix.Zone.utc in |
46 | let today_str = Date_unix.format today "%Y%m%d" in |
47 | match last with |
48 | | Some last -> |
49 | let tomorrow = Date.add_days today 1 in |
50 | if Date.between ~low:today ~high:tomorrow last.date then |
51 | let index = last.index + 1 in |
52 | let path = |
53 | Filename.concat state_dir (sprintf "note-%s-%d.md" today_str index) |
54 | in |
55 | { path; date = today; index } |
56 | else |
57 | let index = 0 in |
58 | let path = |
59 | Filename.concat state_dir (sprintf "note-%s-%d.md" today_str index) |
60 | in |
61 | { path; date = today; index } |
62 | | None -> |
63 | let index = 0 in |
64 | let path = |
65 | Filename.concat state_dir (Core.sprintf "note-%s-%d.md" today_str index) |
66 | in |
67 | { path; date = today; index } |