Matt's Blog

Making links tags work

Fri Jul 14 10:54:28 BST 2006

Quick modification to the last version of the software, to go through the list of tags for an entry and create a correspoding link to that blog category. This doesn't exist as yet since the entry does not currently get piped both to the main page and the tag category, I need to relearn how to open different output streams in Ocaml - from memory it was just open_out channel_name. Should be simple...

... time passes ...

In the end it took about an hour to do, longer than I had hoped. Still, seems pretty functional now. The code for the main ocaml program is below:

blogmain.ml

(* Convert character list to string *)
let explode str = 
  let rec aux n acc = match n with
    | 0 -> acc
    | _ -> aux (n-1) (str.[n-1] :: acc)
  in aux (String.length str) [];;

(* Convert character list to string *)
let implode clst =
  let str = String.create (List.length clst) in
  let rec aux n lst = match lst with
    | [] -> str
    | x :: xs -> str.[n] <- x;  aux (n+1) xs in
  aux 0 clst;;

(* Split a string into a list of substrings based on a delimiter
character *)
let split c str = 
  let rec aux s acc = 
    try  let ind=String.index s c in
         aux (String.sub s (ind+1) ((String.length s) - ind -1 )) 
              ((String.sub s 0 ind)::acc)       
    with Not_found -> List.rev (s::acc) 
  in aux str [];;

(* Strip all whitespace from a string - possibly not what I want to
do, may just want to strip leading whitespace *)
let strip_ws str = 
  List.filter (fun x -> match x with ' ' | '\t' -> false | _ -> true)
  (explode str);;

let cat_str_lst = 
  List.fold_left (fun acc str -> acc ^ " " ^ str) "";;

let main() = 
  let lexbuf = Lexing.from_channel stdin in
  let parselist = BlogParse.main BlogLex.token lexbuf in
  let sort_tags taglst = 
    (* Sort the tags in order of precedence, subject>tag *)
    List.sort 
      (fun (tag1, _) (tag2, _) -> match tag1, tag2 with
      | "subject", _ -> -1
      | _, "subject" -> 1
      | _, _         -> 0) taglst in
  let get_tag_list tagstr = 
    List.map (fun s -> implode (strip_ws s))
             (split ',' tagstr) in
  let print_tag (tag, tagstr) = match tag with
    (* prints a tag with markdown for H3 if subject and 
       in markdown hyperlink form for a category tag list *)
    | "subject" -> "###" ^ tagstr
    | "tags" -> cat_str_lst
          ( (* make each category tag a hyperlink *)
           List.map 
            (fun x -> "[[" ^ x ^ "](blog/blog_" ^ x ^ "/blog_" ^ x ^ ".html)]") 
            (get_tag_list tagstr) )
    | _ -> tag ^ ": " ^ tagstr in
  let extract_tags taglst = 
    (* extracts the tags for an entry as a string *)
    List.fold_left 
      (fun acc tag -> acc ^ (print_tag tag) ^ "\n") 
      "" (sort_tags taglst) in
    begin 
      List.iter 
        (fun (k,tlst,v) -> 
          let cats = 
            List.filter (function "blog" -> false | _ -> true) 
            (get_tag_list 
              (List.fold_left 
              (fun acc (tag, tagstr) -> match tag with
                | "tags" -> acc ^ tagstr
                | _ -> acc) "" tlst)) in
          let outlist = 
            List.map 
              (fun x -> open_out_gen 
                [Open_append; Open_creat] 
                0o644 ("blog_" ^ x ^ ".txt") )
              cats in

        begin
            List.iter 
              (fun x -> 
                Printf.fprintf x
                "##%s\n%s\n%s\n" k (extract_tags tlst)  v) 
              (stdout :: outlist);
            List.iter close_out outlist
        end)
        (List.rev parselist);
    end
  ;;

let _ = Printexc.print main ();;

[code]

[permlink]

code (24)

erlang (5)
ideas (19)
lisp (1)
me (11)
notes (4)
ocaml (1)
physics (45)
qo (7)
unix (6)
vim (3)