(* returns a pair of lists: one for the top-level menu, with a boolean flag indicating which is selected; another for the sub-menu, again with a flag. *) type spec = (string * string * (string * string) list) list let flag tag (uri,txt) = if tag = uri then (uri,txt,true) else (uri,txt,false) let rec find spec tag top sub = match spec, sub with [], None -> (List.rev top, []) | [], Some sub -> (List.rev top, sub) | (uri,txt,ch)::spec, _ -> if tag = uri or List.exists (fun (u,_) -> tag=u) ch then find spec tag ((uri,txt,true)::top) (Some (List.map (flag tag) ch)) else find spec tag ((uri,txt,false)::top) sub let rec iter f i list = match list with [] -> () | x::xs -> f i x; iter f (i+1) xs open Buffer let gen spec tag = let buf = create 1024 in let sel = ref 0 in let each top_p i (uri,txt,select_p) = add_string buf (Printf.sprintf "