refactoring
This commit is contained in:
		
							
								
								
									
										77
									
								
								src/webcc.ml
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								src/webcc.ml
									
									
									
									
									
								
							@@ -1,15 +1,20 @@
 | 
				
			|||||||
let input = ref []
 | 
					let input = ref []
 | 
				
			||||||
let output = ref ""
 | 
					let output = ref ""
 | 
				
			||||||
 | 
					let gen_index = ref false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let spec =
 | 
					let spec =
 | 
				
			||||||
  [
 | 
					  [
 | 
				
			||||||
    "-o", Arg.Set_string output,
 | 
					    ("-o", Arg.Set_string output,
 | 
				
			||||||
    " file.html Specify the output file (default is stdout).";
 | 
					     " file.html Specify the output file (default is stdout).");
 | 
				
			||||||
 | 
					    ("-i", Arg.Set gen_index,
 | 
				
			||||||
    "--", Rest(fun s -> input := s :: !input),
 | 
					     " generate a post index instead of compiling individual posts.");
 | 
				
			||||||
    " Consider all remaining arguments as input file names.";
 | 
					    ("--", 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 *)
 | 
					(** Utitilies *)
 | 
				
			||||||
let with_open_in fn f =
 | 
					let with_open_in fn f =
 | 
				
			||||||
  let ic = open_in fn in
 | 
					  let ic = open_in fn in
 | 
				
			||||||
@@ -23,7 +28,7 @@ let with_open_out fn f =
 | 
				
			|||||||
  | r -> close_out oc; r
 | 
					  | r -> close_out oc; r
 | 
				
			||||||
  | exception e -> close_out_noerr oc; raise e
 | 
					  | exception e -> close_out_noerr oc; raise e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let read_metadata ic =
 | 
					let read_metadata ic : post_metadata =
 | 
				
			||||||
  let rec go lst =
 | 
					  let rec go lst =
 | 
				
			||||||
    let line =
 | 
					    let line =
 | 
				
			||||||
      try input_line ic
 | 
					      try input_line ic
 | 
				
			||||||
@@ -32,11 +37,23 @@ let read_metadata ic =
 | 
				
			|||||||
    match String.split_on_char ':' line with
 | 
					    match String.split_on_char ':' line with
 | 
				
			||||||
    | tag::value1::rest -> go ((tag, String.trim (String.concat ":" (value1::rest)))::lst)
 | 
					    | tag::value1::rest -> go ((tag, String.trim (String.concat ":" (value1::rest)))::lst)
 | 
				
			||||||
    | _ -> 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 *)
 | 
					(** Functions for processing an individual post *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let format_post ~title ~tags ~date ~contents =
 | 
					let format_page ~title ~contents =
 | 
				
			||||||
  String.concat "" [
 | 
					  String.concat "" [
 | 
				
			||||||
{|<!DOCTYPE html>
 | 
					{|<!DOCTYPE html>
 | 
				
			||||||
<head>
 | 
					<head>
 | 
				
			||||||
@@ -58,10 +75,8 @@ let format_post ~title ~tags ~date ~contents =
 | 
				
			|||||||
    <span class="menu-item"><a href="/feed.xml">atom feed</a></span>
 | 
					    <span class="menu-item"><a href="/feed.xml">atom feed</a></span>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div id="wrapper">
 | 
					  <div id="wrapper">
 | 
				
			||||||
    <h1>|}; title; {|</h1>|};
 | 
					    <h1>|}; title; {|</h1>|}; 
 | 
				
			||||||
  {|<p class="author">|}; date; {|</p>|};
 | 
					    contents;
 | 
				
			||||||
  {|<div class="abstract"><p>Tags: |}; tags; {|</p></div>|};
 | 
					 | 
				
			||||||
  {|<div class="post">|}; contents; {|</div>|};
 | 
					 | 
				
			||||||
{| </div>
 | 
					{| </div>
 | 
				
			||||||
  <hr />
 | 
					  <hr />
 | 
				
			||||||
  <div class="footer">
 | 
					  <div class="footer">
 | 
				
			||||||
@@ -70,25 +85,38 @@ let format_post ~title ~tags ~date ~contents =
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</body>|}]
 | 
					</body>|}]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let format_post ~title ~tags ~date ~contents =
 | 
				
			||||||
 | 
					  let inner = String.concat "" [
 | 
				
			||||||
 | 
					  {|<p class="author">|}; date; {|</p>|};
 | 
				
			||||||
 | 
					  {|<div class="abstract"><p>Tags: |}; tags; {|</p></div>|};
 | 
				
			||||||
 | 
					  {|<div class="post">|}; contents; {|</div>|}
 | 
				
			||||||
 | 
					                 ] in
 | 
				
			||||||
 | 
					  format_page ~title ~contents:inner
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(* convert contents from [ic] to a post webpage, output to [oc] *)
 | 
					(* convert contents from [ic] to a post webpage, output to [oc] *)
 | 
				
			||||||
let process ic oc =
 | 
					let process ic oc =
 | 
				
			||||||
  let metadata = read_metadata ic in
 | 
					  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 md = Omd.of_channel ic in
 | 
				
			||||||
  let date = ISO8601.Permissive.date (lookup_metadata "date") in
 | 
					 | 
				
			||||||
  let html = format_post
 | 
					  let html = format_post
 | 
				
			||||||
               ~title:(lookup_metadata "title")
 | 
					               ~title:(metadata.title)
 | 
				
			||||||
               ~tags:(lookup_metadata "tags")
 | 
					               ~tags:(String.concat ", " metadata.tags)
 | 
				
			||||||
               ~date:(ISO8601.Permissive.string_of_date date)
 | 
					               ~date:(ISO8601.Permissive.string_of_date metadata.date)
 | 
				
			||||||
               ~contents:(Omd.to_html md)
 | 
					               ~contents:(Omd.to_html md)
 | 
				
			||||||
  in
 | 
					  in
 | 
				
			||||||
  output_string oc html
 | 
					  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 () =
 | 
					let main () =
 | 
				
			||||||
  Arg.parse (Arg.align spec)
 | 
					  Arg.parse (Arg.align spec)
 | 
				
			||||||
    (fun s -> input := s :: !input)
 | 
					    (fun s -> input := s :: !input)
 | 
				
			||||||
@@ -99,12 +127,7 @@ let main () =
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
      with_open_out !output f
 | 
					      with_open_out !output f
 | 
				
			||||||
  in
 | 
					  in
 | 
				
			||||||
  with_output @@ fun oc ->
 | 
					  with_output compile_posts
 | 
				
			||||||
  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 () =
 | 
					let () =
 | 
				
			||||||
  try
 | 
					  try
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user