From 6b657940873198e08bfefcb4bc41d712acb964e5 Mon Sep 17 00:00:00 2001 From: Dan Frumin Date: Fri, 28 Aug 2020 17:58:45 +0200 Subject: [PATCH] first commit --- README | 1 + dune-project | 1 + src/dune | 3 ++ src/webcc.ml | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 README create mode 100644 dune-project create mode 100644 src/dune create mode 100644 src/webcc.ml diff --git a/README b/README new file mode 100644 index 0000000..f2268ba --- /dev/null +++ b/README @@ -0,0 +1 @@ +UwU diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..45acd3f --- /dev/null +++ b/dune-project @@ -0,0 +1 @@ +(lang dune 2.7) diff --git a/src/dune b/src/dune new file mode 100644 index 0000000..dcbb772 --- /dev/null +++ b/src/dune @@ -0,0 +1,3 @@ +(executable + (name webcc) + (libraries omd)) diff --git a/src/webcc.ml b/src/webcc.ml new file mode 100644 index 0000000..95dae42 --- /dev/null +++ b/src/webcc.ml @@ -0,0 +1,115 @@ +let input = ref [] +let output = ref "" + +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."; + ] + + +let with_open_in fn f = + let ic = open_in fn in + match f ic with + | r -> close_in ic; r + | exception e -> close_in_noerr ic; raise e + +let with_open_out fn f = + let oc = open_out fn in + match f oc with + | r -> close_out oc; r + | exception e -> close_out_noerr oc; raise e + +let read_metadata ic = + let rec go lst = + let line = + try input_line ic + with End_of_file -> "" + in + match String.split_on_char ':' line with + | tag::value1::rest -> go ((tag, String.trim (String.concat ":" (value1::rest)))::lst) + | _ -> lst + in go [] + +let format_post ~title ~tags ~date ~contents = + String.concat "" [ +{| + + + + + + + + |}; title; {||}; +{| + + +
+

|}; title; {|

|}; + {|

|}; date; {|

|}; + {|

Tags: |}; tags; {|

|}; + {|
|}; contents; {|
|}; +{|
+
+ +|}] + + +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 html = format_post + ~title:(lookup_metadata "title") + ~tags:(lookup_metadata "tags") + ~date:(lookup_metadata "date") + ~contents:(Omd.to_html md) + in + output_string oc html + +let main () = + Arg.parse (Arg.align spec) + (fun s -> input := s :: !input) + "webcc [options] [inputfile1 .. inputfileN] [options]"; + let with_output f = + if !output = "" then + f stdout + 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 + +let () = + try + main () + with + | Sys_error msg -> + Printf.eprintf "Error: %s\n" msg; + exit 1 + | exn -> + Printf.eprintf "Error: %s\n" (Printexc.to_string exn); + Printexc.print_backtrace stderr; + exit 1