diff --git a/src/webcc.ml b/src/webcc.ml index e75195f..52a93c5 100644 --- a/src/webcc.ml +++ b/src/webcc.ml @@ -1,15 +1,20 @@ let input = ref [] let output = ref "" +let gen_index = ref false let spec = [ - "-o", Arg.Set_string output, - " file.html Specify the output file (default is stdout)."; - - "--", Rest(fun s -> input := s :: !input), - " Consider all remaining arguments as input file names."; + ("-o", Arg.Set_string output, + " file.html Specify the output file (default is stdout)."); + ("-i", Arg.Set gen_index, + " generate a post index instead of compiling individual posts."); + ("--", Rest(fun s -> input := s :: !input), + " Consider all remaining arguments as input file names.") ] +type post_metadata = { title : string ; date : float ; tags : string list ; + other : (string * string) list } + (** Utitilies *) let with_open_in fn f = let ic = open_in fn in @@ -23,7 +28,7 @@ let with_open_out fn f = | r -> close_out oc; r | exception e -> close_out_noerr oc; raise e -let read_metadata ic = +let read_metadata ic : post_metadata = let rec go lst = let line = try input_line ic @@ -32,11 +37,23 @@ let read_metadata ic = match String.split_on_char ':' line with | tag::value1::rest -> go ((tag, String.trim (String.concat ":" (value1::rest)))::lst) | _ -> lst - in go [] + in + let md = go [] in + let lookup k = + match List.assoc_opt k md with + | Some s -> s + | None -> "-" + in + let date = ISO8601.Permissive.date (lookup "date") in + { title = lookup "title"; + date = date; + tags = String.split_on_char ',' (lookup "tags"); + other = md } + (** Functions for processing an individual post *) -let format_post ~title ~tags ~date ~contents = +let format_page ~title ~contents = String.concat "" [ {| @@ -58,10 +75,8 @@ let format_post ~title ~tags ~date ~contents = atom feed
-

|}; title; {|

|}; - {|

|}; date; {|

|}; - {|

Tags: |}; tags; {|

|}; - {|
|}; contents; {|
|}; +

|}; title; {|

|}; + contents; {|

|}] +let format_post ~title ~tags ~date ~contents = + let inner = String.concat "" [ + {|

|}; date; {|

|}; + {|

Tags: |}; tags; {|

|}; + {|
|}; contents; {|
|} + ] in + format_page ~title ~contents:inner (* convert contents from [ic] to a post webpage, output to [oc] *) let process ic oc = let metadata = read_metadata ic in - let lookup_metadata k = - match List.assoc_opt k metadata with - | Some s -> s - | None -> "-" - in let md = Omd.of_channel ic in - let date = ISO8601.Permissive.date (lookup_metadata "date") in let html = format_post - ~title:(lookup_metadata "title") - ~tags:(lookup_metadata "tags") - ~date:(ISO8601.Permissive.string_of_date date) + ~title:(metadata.title) + ~tags:(String.concat ", " metadata.tags) + ~date:(ISO8601.Permissive.string_of_date metadata.date) ~contents:(Omd.to_html md) in output_string oc html +let compile_posts oc = + if !input = [] then process stdin oc + else begin + let f filename = with_open_in filename @@ fun ic -> process ic oc in + List.iter f !input + end + + +(** Generating index of posts *) +(* let generate_index oc = () *) + +(** main *) let main () = Arg.parse (Arg.align spec) (fun s -> input := s :: !input) @@ -99,12 +127,7 @@ let main () = else with_open_out !output f in - with_output @@ fun oc -> - if !input = [] then process stdin oc - else begin - let f filename = with_open_in filename @@ fun ic -> process ic oc in - List.iter f !input - end + with_output compile_posts let () = try