diff options
Diffstat (limited to 'lib/render/emit_csv.ml')
| -rw-r--r-- | lib/render/emit_csv.ml | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/render/emit_csv.ml b/lib/render/emit_csv.ml new file mode 100644 index 0000000..b478265 --- /dev/null +++ b/lib/render/emit_csv.ml @@ -0,0 +1,44 @@ +(* emit_csv.ml *) +module T = Template + +let escape_field s = + let needs = + String.exists (fun c -> c = ',' || c = '"' || c = '\n' || c = '\r') s + in + if not needs then s + else begin + let b = Buffer.create (String.length s + 8) in + Buffer.add_char b '"'; + String.iter (fun c -> if c = '"' then Buffer.add_string b "\"\"" else Buffer.add_char b c) s; + Buffer.add_char b '"'; + Buffer.contents b + end + +let get v k = match v with T.Obj kvs -> List.assoc_opt k kvs | _ -> None +let s v k = match get v k with Some (T.Str x) -> x | _ -> "" +let nested v a b = match get v a with Some inner -> s inner b | None -> "" + +let columns = + [ "date"; "rite"; "season"; "week"; "slug"; "rank"; "colour"; "subject"; + "name_la"; "name_en"; "first"; "gospel"; "comms" ] + +let row ~rite d = + let comms = + match get d "comms" with + | Some (T.List l) -> String.concat " " (List.map (fun c -> s c "slug") l) + | _ -> "" + in + String.concat "," + (List.map escape_field + [ s d "iso"; rite; s d "season"; s d "week"; s d "slug"; s d "rank"; + s d "colour"; s d "subject"; nested d "name" "la"; nested d "name" "en"; + s d "first"; s d "gospel"; comms ]) + +let year v = + let rite = s v "rite" in + let days = match get v "days" with Some (T.List l) -> l | _ -> [] in + let b = Buffer.create (64 * 400) in + Buffer.add_string b (String.concat "," columns); + Buffer.add_char b '\n'; + List.iter (fun d -> Buffer.add_string b (row ~rite d); Buffer.add_char b '\n') days; + Buffer.contents b |
