Previous Up

2.6  Standalone program bmktrans

This program handles the command line options and calls the html file generator.

open Analyze
open Print

(* configurable default options *)
let directory = ref "bookmarks"
let title = ref None
let footer =
  ref (Some ("<address>Made with "^
       "<a href=\"\">"^
let depth = ref 3
let background_color = ref "#FFFFFF"
let text_color = ref "#000000"
let link_color = ref "#660000"
let vlink_color = ref "#000066"
let alink_color = ref "#660066"
let bar_width = ref 40
let bar_colors = ref (new circular_list)
let bc1 = new circular_list
let _ = bc1#add (new color "#009966")
let _ = !bar_colors#add bc1
let invisible_bar = ref false
let list_colors = ref (new circular_list)
let lc1 = new circular_list
let _ = lc1#add (new color "#99FF99")
let _ = lc1#add (new color "#CCFFCC")
let _ = !list_colors#add lc1
let keywords = ref Keywords.empty
let top = ref None
(* maximal age in seconds to be marked as new *)
let max_new_age = ref (3600. *. 24. *. 15.)
let new_marker_start = ref ""
let new_marker_end = ref " <b><i>NEW</i></b>"
let separator = ref " "
let css = ref None

let new_cb = ref true
let new_cl = ref true

let set_options () =
  let inputfile = ref ""
  in Arg.parse
         [("-directory", Arg.String (fun d -> directory := d),
           "<dir>: set output directory to <dir>\n"^
           "\t<dir> must exist before the execution of bmktrans\n"^
           "\tdefault value: bookmarks");
          ("-title", Arg.String (fun t -> title := Some t),
           "<string>: set running document title to <string>\n"^
           "\tdefault value taken from input file");
          ("-footer", Arg.String (fun f -> footer := Some f),
           "<string>: set running document footer to <string>\n"^
           "\tdefault value: "^"<address>Made with "^
           "<a href=\"\">"^
          ("-depth", Arg.Int (fun d -> depth := d),
           "<int>: set the tree pruning depth to <int>\n"^
           "\tdefault value: 3");
          ("-css", Arg.String (fun f -> css := Some f),
           "<url>: use the given url as style sheet\n"^
           "\tinhibits the bgcolor, text, link, vlink, alink options\n"^
           "\tdefault value: None");
          ("-bgcolor", Arg.String (fun c -> background_color := c),
           "<color>: set the background color to <color>\n"^
           "\tdefault value: #FFFFFF");
          ("-text", Arg.String (fun c -> text_color := c),
           "<color>: set the text color to <color>\n"^
           "\tdefault value: #000000");
          ("-link", Arg.String (fun c -> link_color := c),
           "<color>: set the non visited link color to <color>\n"^
           "\tdefault value: #660000");
          ("-vlink", Arg.String (fun c -> vlink_color := c),
           "<color>: set the visited link color to <color>\n"^
           "\tdefault value: #000066");
          ("-alink", Arg.String (fun c -> alink_color := c),
           "<color>: set the active link color to <color>\n"^
           "\tdefault value: #660066");
          ("-barwidth", Arg.Int (fun w -> bar_width := w),
           "<int>: set the bar width to <int>\n"^
           "\tdefault value: 40");
             (fun cs ->
                if cs = "invisible" then invisible_bar := true
                else begin
                  if !new_cb then begin
                    new_cb := false;
                    bar_colors := new circular_list
                  let cb = new circular_list in
                    for i = 0 to ((String.length cs)/7)-1 do
                      cb#add (new color (String.sub cs (i*7) 7))
                    !bar_colors#add cb
             "<colors>: set the bar colors to <colors>\n"^
             "\ta value of invisible is possible\n"^
             "\tdefault value: #009966\n"^
             "\ttry using it several times...");
           Arg.String (fun cs ->
                         if !new_cl then begin
                           new_cl := false;
                           list_colors := new circular_list
                         let cl = new circular_list in
                           for i = 0 to ((String.length cs)/7)-1 do
                             cl#add (new color (String.sub cs (i*7) 7))
                           !list_colors#add cl),
           "<colors>: set the lists colors to <colors>\n"^
           "\tdefault value: #99FF99#CCFFCC\n"^
           "\ttry using it several times...");
           Arg.String (fun s -> top := Some s),
           "<string>: set the root of the produced hierarchy");
           Arg.String (fun s -> keywords := Keywords.add s !keywords),
           "<string>: remove from the output any folder with that name\n"^
           "\tcan appear any number of times");
           Arg.Float (fun f -> max_new_age := f),
           "<float>: set the maximal age (in seconds) to be marked as new\n"^
           "\tdefault value: 1296000 (15 days)");
           Arg.String (fun s -> new_marker_start := s),
           "<string>: set the part of the new marker that is inserted\n"^
           "\tbefore the bookmark or the folder name\n"^
           "\tdefault value: \"\"");
           Arg.String (fun s -> new_marker_end := s),
           "<string>: set the part of the new marker that is inserted\n"^
           "\tafter the bookmark or the folder name\n"^
           "\tdefault value: \" <b><i>NEW</i></b>\"");
           Arg.String (fun s -> separator := s),
           "<string>: set the separator between the URL and its description\n"^
           "\tdefault value: \" \"")]
         (fun f -> inputfile := f)
         ("usage: bmktrans [options] <file>\n"^
          "\t<file> has to obey the syntax of netscape's bookmarks file\n"^
          "\t[options] are described below with their default value\n"^
          "\ncolor syntax: <color> is in the hexadecimal form #RRVVBB\n"^
          "\t<colors> is a sequence of <color> (see example below)\n"^

Main function. It creates the output directory if necessary, then puts a 1x1 transparent gif in it and calls the parser followed by the generator.

let main () =
  let filename = set_options () in
    if not(Sys.file_exists !directory) then
      Unix.mkdir !directory 0o755;
    let pixel = Filename.concat !directory "1x1.gif" in
      if not(Sys.file_exists pixel)
      then begin
        let chpix = open_out pixel in
          output_string chpix
          output_string chpix
            "!\014Made with GIMP\000!\004\001\n";
          output_string chpix
          output_string chpix
          close_out chpix
      let doc = filter (analyze filename) !keywords in
      let doc' = match !top with
          None -> doc
        | Some s -> new_top doc s in
        Print.hierarchie doc'
          ~title:!title ~footer:!footer
          ~dir:!directory ~depth:!depth
          ~css:!css ~bg:!background_color ~text:!text_color
          ~link:!link_color ~vlink:!vlink_color ~alink:!alink_color
          ~bar_width:!bar_width ~bar:!bar_colors ~list:!list_colors
          ~visibility:!invisible_bar ~new_age:!max_new_age
          ~new_start:!new_marker_start ~new_end:!new_marker_end

let _ = Printexc.catch main ()

Previous Up