first commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								dune-project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dune-project
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					(lang dune 2.7)
 | 
				
			||||||
							
								
								
									
										115
									
								
								src/webcc.ml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/webcc.ml
									
									
									
									
									
										Normal file
									
								
							@@ -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 "" [
 | 
				
			||||||
 | 
					{|<!DOCTYPE html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="utf-8" />
 | 
				
			||||||
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
 | 
				
			||||||
 | 
					  <link rel="stylesheet" href="/static/style.css" />
 | 
				
			||||||
 | 
					  <link rel="alternate" href="/feed.xml" type="application/atom+xml" title="Atom feed" />
 | 
				
			||||||
 | 
					  <script type="text/x-mathjax-config">
 | 
				
			||||||
 | 
					    MathJax.Hub.Config({
 | 
				
			||||||
 | 
					    tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
 | 
				
			||||||
 | 
					    });</script>
 | 
				
			||||||
 | 
					  <script type="text/javascript" src="https://groupoid.moe/MathJax/MathJax.js?config=TeX-MML-AM_CHTML"></script>
 | 
				
			||||||
 | 
					  <title>|}; title; {|</title>|};
 | 
				
			||||||
 | 
					{|</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="menu">
 | 
				
			||||||
 | 
					    <span class="menu-item"><a href="/">home</a></span>
 | 
				
			||||||
 | 
					    <span class="menu-item"><a href="/pages/links.html">linkroll</a></span>
 | 
				
			||||||
 | 
					    <span class="menu-item"><a href="/feed.xml">atom feed</a></span>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  <div id="wrapper">
 | 
				
			||||||
 | 
					    <h1>|}; title; {|</h1>|};
 | 
				
			||||||
 | 
					  {|<p class="author">|}; date; {|</p>|};
 | 
				
			||||||
 | 
					  {|<div class="abstract"><p>Tags: |}; tags; {|</p></div>|};
 | 
				
			||||||
 | 
					  {|<div class="post">|}; contents; {|</div>|};
 | 
				
			||||||
 | 
					{| </div>
 | 
				
			||||||
 | 
					  <hr />
 | 
				
			||||||
 | 
					  <div class="footer">
 | 
				
			||||||
 | 
					    <p><img src="/static/created0.jpg" /></p>
 | 
				
			||||||
 | 
					    <p><a href="/feed.xml">atom</a></p>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>|}]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
		Reference in New Issue
	
	Block a user