(* camlp4r ./pa_html.cmo *) (* $Id: update.ml,v 4.34 2004/12/14 09:30:17 ddr Exp $ *) (* Copyright (c) 1998-2005 INRIA *) open Config; open Def; open Gutil; open Util; exception ModErr; type create_info = (option date * string * death * option date * string); type create = [ Create of sex and option create_info | Link ]; type key = (string * string * int * create * string); value has_children base u = List.exists (fun ifam -> let des = doi base ifam in Array.length des.children > 0) (Array.to_list u.family) ; value infer_death conf birth = match birth with [ Some (Dgreg d _) -> let a = Gutil.year_of (Gutil.time_gone_by d conf.today) in if a > 120 then DeadDontKnowWhen else if a <= 80 then NotDead else DontKnowIfDead | _ -> DontKnowIfDead ] ; value print_same_name conf base p = match Gutil.find_same_name base p with [ [_] -> () | pl -> do { html_p conf; Wserver.wprint "%s:\n" (capitale (transl conf "persons having the same name")); tag "ul" begin List.iter (fun p -> do { html_li conf; stag "a" "href=\"%s%s\"" (commd conf) (acces conf base p) begin Wserver.wprint "%s.%d %s" (p_first_name base p) p.occ (p_surname base p); end; Wserver.wprint "%s\n" (Date.short_dates_text conf base p) }) pl; end } ] ; value print_return conf = do { html_p conf; tag "form" "method=POST action=\"%s\"" conf.command begin List.iter (fun (x, v) -> Wserver.wprint "\n" x (quote_escaped (decode_varenv v))) (conf.henv @ conf.env); Wserver.wprint "\n"; Wserver.wprint "\n" (capitale (transl conf "back")); end } ; value print_err_unknown conf base (f, s, o) = let title _ = Wserver.wprint "%s" (capitale (transl conf "error")) in do { rheader conf title; Wserver.wprint "%s: %s.%d %s\n" (capitale (transl conf "unknown person")) f o s; print_return conf; trailer conf; raise ModErr } ; value insert_string base s = try base.func.index_of_string s with [ Not_found -> let i = Adef.istr_of_int base.data.strings.len in do { base.func.patch_string i s; i } ] ; value update_misc_names_of_family base p u = match p.sex with [ Male -> List.iter (fun ifam -> let des = doi base ifam in let cpl = coi base ifam in List.iter (fun ip -> List.iter (fun name -> if not (List.memq ip (person_ht_find_all base name)) then person_ht_add base name ip else ()) (person_misc_names base (poi base ip))) [mother cpl :: Array.to_list des.children]) (Array.to_list u.family) | _ -> () ] ; value delete_topological_sort_v conf base = let bfile = Util.base_path [] (conf.bname ^ ".gwb") in do { let tstab_file = Filename.concat bfile "tstab_visitor" in try Sys.remove tstab_file with [ Sys_error _ -> () ]; let tstab_file = Filename.concat bfile "restrict" in try Sys.remove tstab_file with [ Sys_error _ -> () ] } ; value delete_topological_sort conf base = let _ = delete_topological_sort_v conf base in let bfile = Util.base_path [] (conf.bname ^ ".gwb") in let tstab_file = Filename.concat bfile "tstab" in try Sys.remove tstab_file with [ Sys_error _ -> () ] ; value gen_someone_txt (p_first_name, p_surname) conf base p = p_first_name base p ^ (if p.occ = 0 then "" else "." ^ string_of_int p.occ) ^ " " ^ p_surname base p ; value print_someone conf base p = Wserver.wprint "%s%s %s" (p_first_name base p) (if p.occ = 0 then "" else "." ^ string_of_int p.occ) (p_surname base p) ; value print_first_name conf base p = Wserver.wprint "%s%s" (p_first_name base p) (if p.occ = 0 then "" else "." ^ string_of_int p.occ) ; value print_someone_strong conf base p = Wserver.wprint "%s%s %s" (p_first_name base p) (if p.occ = 0 then "" else "." ^ string_of_int p.occ) (p_surname base p) ; value print_first_name_strong conf base p = Wserver.wprint "%s%s" (p_first_name base p) (if p.occ = 0 then "" else "." ^ string_of_int p.occ) ; value print_src conf name field = tag "table" "border=1" begin tag "tr" "align=left" begin tag "td" begin Wserver.wprint "%s" (capitale (transl_nth conf "source/sources" 0)); end; tag "td" begin Wserver.wprint "\n" name (match field with [ s when s <> "" -> " value=\"" ^ quote_escaped s ^ "\"" | _ -> "" ]); end; end; end ; value print_error conf base = fun [ AlreadyDefined p -> Wserver.wprint (fcapitale (ftransl conf "name %s already used by %tthis person%t")) ("\"" ^ p_first_name base p ^ "." ^ string_of_int p.occ ^ " " ^ p_surname base p ^ "\"") (fun _ -> Wserver.wprint "" (commd conf) (acces conf base p)) (fun _ -> Wserver.wprint ".") | OwnAncestor p -> do { print_someone_strong conf base p; Wserver.wprint "\n%s" (transl conf "would be his/her own ancestor") } | BadSexOfMarriedPerson p -> Wserver.wprint "%s." (capitale (transl conf "cannot change sex of a married person")) ] ; value print_someone_ref conf base p = Wserver.wprint "\n%s%s %s" (commd conf) (acces conf base p) (p_first_name base p) (if p.occ = 0 then "" else "." ^ string_of_int p.occ) (p_surname base p) ; value someone_ref_text conf base p = "\n" ^ p_first_name base p ^ (if p.occ = 0 then "" else "." ^ string_of_int p.occ) ^ " " ^ p_surname base p ^ "" ; value print_first_name_ref conf base p = Wserver.wprint "%s" (someone_ref_text conf base p) ; value print_warning conf base = fun [ BirthAfterDeath p -> Wserver.wprint (ftransl conf "%t died before his/her birth") (fun _ -> do { print_someone_strong conf base p; Wserver.wprint "%s" (Date.short_dates_text conf base p) }) | IncoherentSex p _ _ -> Wserver.wprint (fcapitale (ftransl conf "%t's sex is not coherent with his/her relations")) (fun _ -> print_someone_strong conf base p) | ChangedOrderOfChildren ifam des before -> let cpl = coi base ifam in let fath = poi base (father cpl) in let moth = poi base (mother cpl) in do { Wserver.wprint "%s\n" (capitale (transl conf "changed order of children")); Wserver.wprint "->\n"; Wserver.wprint "%s" (someone_ref_text conf base fath ^ "\n" ^ transl_nth conf "and" 0 ^ someone_ref_text conf base moth ^ "\n"); Wserver.wprint "\n" } | ChildrenNotInOrder ifam des elder x -> let cpl = coi base ifam in do { Wserver.wprint (fcapitale (ftransl conf "the following children of %t and %t are not in order")) (fun _ -> print_someone_strong conf base (poi base (father cpl))) (fun _ -> print_someone_strong conf base (poi base (mother cpl))); Wserver.wprint ":\n"; Wserver.wprint "" } | DeadTooEarlyToBeFather father child -> Wserver.wprint (ftransl conf "\ %t is born more than 2 years after the death of his/her father %t") (fun _ -> do { print_someone_strong conf base child; Wserver.wprint "%s" (Date.short_dates_text conf base child) }) (fun _ -> do { print_someone_strong conf base father; Wserver.wprint "%s" (Date.short_dates_text conf base father) }) | MarriageDateAfterDeath p -> Wserver.wprint (fcapitale (ftransl conf "marriage of %t after his/her death")) (fun _ -> do { print_someone_strong conf base p; Wserver.wprint "%s" (Date.short_dates_text conf base p) }) | MarriageDateBeforeBirth p -> Wserver.wprint (fcapitale (ftransl conf "marriage of %t before his/her birth")) (fun _ -> do { print_someone_strong conf base p; Wserver.wprint "%s" (Date.short_dates_text conf base p) }) | MotherDeadAfterChildBirth mother child -> Wserver.wprint (ftransl conf "%t is born after the death of his/her mother %t") (fun _ -> do { print_someone_strong conf base child; Wserver.wprint "%s" (Date.short_dates_text conf base child) }) (fun _ -> do { print_someone_strong conf base mother; Wserver.wprint "%s" (Date.short_dates_text conf base mother) }) | ParentBornAfterChild p c -> do { print_someone_strong conf base p; Wserver.wprint "\n%s\n" (transl conf "is born after his/her child"); print_someone_strong conf base c } | ParentTooYoung p a -> do { print_someone_strong conf base p; Wserver.wprint "\n%s\n" (transl conf "is a very young parent"); Wserver.wprint "(%s)" (Date.string_of_age conf a); } | TitleDatesError p t -> Wserver.wprint (fcapitale (ftransl conf "%t has incorrect title dates: %t")) (fun _ -> do { print_someone_strong conf base p; Wserver.wprint "%s" (Date.short_dates_text conf base p) }) (fun _ -> Wserver.wprint "%s %s %s-%s" (sou base t.t_ident) (sou base t.t_place) (match Adef.od_of_codate t.t_date_start with [ Some d -> Date.string_of_date conf d | _ -> "" ]) (match Adef.od_of_codate t.t_date_end with [ Some d -> Date.string_of_date conf d | _ -> "" ])) | UndefinedSex p -> Wserver.wprint (fcapitale (ftransl conf "undefined sex for %t")) (fun _ -> print_someone_strong conf base p) | YoungForMarriage p a -> do { print_someone_strong conf base p; Wserver.wprint "\n"; Wserver.wprint (ftransl conf "married at age %t") (fun _ -> Wserver.wprint "%s" (Date.string_of_age conf a)) } ] ; value print_warnings conf base wl = if wl = [] then () else do { html_p conf; Wserver.wprint "%s\n" (capitale (transl conf "warnings")); tag "ul" begin List.iter (fun w -> do { html_li conf; print_warning conf base w; Wserver.wprint "\n" }) wl; end } ; value error conf base x = let title _ = Wserver.wprint "%s" (capitale (transl conf "error")) in do { rheader conf title; print_error conf base x; Wserver.wprint "\n"; print_return conf; trailer conf; raise ModErr } ; value error_locked conf base = let title _ = Wserver.wprint "%s" (capitale (transl conf "error")) in do { rheader conf title; Wserver.wprint (fcapitale (ftransl conf "the file is temporarily locked: please try again")); Wserver.wprint ".\n"; trailer conf } ; value error_digest conf base = let title _ = Wserver.wprint "%s" (capitale (transl conf "error")) in do { rheader conf title; print_link_to_welcome conf True; Wserver.wprint (fcapitale (ftransl conf "\ the base has changed; do \"back\", \"reload\", and refill the form")); Wserver.wprint ".\n"; trailer conf; raise ModErr } ; value digest_person (p : person) = Iovalue.digest p; value digest_family (fam : family) (cpl : couple) (des : descend) = Iovalue.digest (fam, cpl, des) ; value get var key env = match p_getenv env (var ^ "_" ^ key) with [ Some v -> v | None -> failwith (var ^ "_" ^ key ^ " unbound") ] ; value get_number var key env = p_getint env (var ^ "_" ^ key); value bad_date conf d = let title _ = Wserver.wprint "%s" (capitale (transl conf "error")) in do { rheader conf title; Wserver.wprint "%s:\n" (capitale (transl conf "incorrect date")); match d with [ {day = 0; month = 0; year = a} -> Wserver.wprint "%d" a | {day = 0; month = m; year = a} -> Wserver.wprint "%d/%d" m a | {day = j; month = m; year = a} -> Wserver.wprint "%d/%d/%d" j m a ]; trailer conf; raise ModErr } ; value int_of_field s = try Some (int_of_string (strip_spaces s)) with [ Failure _ -> None ] ; value reconstitute_date_dmy conf var = let (prec, y) = let y = get var "yyyy" conf.env in let prec = p_getenv conf.env (var ^ "_prec") in let len = String.length y in if len > 1 then match (y.[0], y.[len-1]) with [ ('?', _) -> (Some "maybe", String.sub y 1 (len - 1)) | ('~', _) -> (Some "about", String.sub y 1 (len - 1)) | ('/', '/') -> (Some "about", String.sub y 1 (len - 2)) | ('<', _) | ('/', _) -> (Some "before", String.sub y 1 (len - 1)) | ('>', _) -> (Some "after", String.sub y 1 (len - 1)) | (_, '/') -> (Some "after", String.sub y 0 (len - 1)) | _ -> (prec, y) ] else (prec, y) in let (force_f_cal, m) = let m = get var "mm" conf.env in match String.uppercase m with [ "VD" -> (True, Some 1) | "BR" -> (True, Some 2) | "FM" -> (True, Some 3) | "NI" -> (True, Some 4) | "PL" -> (True, Some 5) | "VT" -> (True, Some 6) | "GE" -> (True, Some 7) | "FL" -> (True, Some 8) | "PR" -> (True, Some 9) | "ME" -> (True, Some 10) | "TH" -> (True, Some 11) | "FT" -> (True, Some 12) | "JC" -> (True, Some 13) | _ -> (False, int_of_field m) ] in let d = match int_of_field y with [ Some y -> let prec = match prec with [ Some "about" -> About | Some "maybe" -> Maybe | Some "before" -> Before | Some "after" -> After | Some "oryear" -> match get_number var "oryear" conf.env with [ Some y -> OrYear y | None -> Sure ] | Some "yearint" -> match get_number var "oryear" conf.env with [ Some y -> YearInt y | None -> Sure ] | _ -> Sure ] in match m with [ Some m -> match get_number var "dd" conf.env with [ Some d -> let d = {day = d; month = m; year = y; prec = prec; delta = 0} in if d.day >= 1 && d.day <= 31 && d.month >= 1 && d.month <= 13 then Some d else bad_date conf d | None -> let d = {day = 0; month = m; year = y; prec = prec; delta = 0} in if d.month >= 1 && d.month <= 13 then Some d else bad_date conf d ] | None -> Some {day = 0; month = 0; year = y; prec = prec; delta = 0} ] | None -> None ] in (d, force_f_cal) ; value check_greg_day conf d = if d.day > nb_days_in_month d.month d.year then bad_date conf d else () ; value reconstitute_date conf var = match reconstitute_date_dmy conf var with [ (Some d, False) -> let (d, cal) = match p_getenv conf.env (var ^ "_cal") with [ Some "G" | None -> do { check_greg_day conf d; (d, Dgregorian) } | Some "J" -> (Calendar.gregorian_of_julian d, Djulian) | Some "F" -> (Calendar.gregorian_of_french d, Dfrench) | Some "H" -> (Calendar.gregorian_of_hebrew d, Dhebrew) | _ -> (d, Dgregorian) ] in Some (Dgreg d cal) | (Some d, True) -> Some (Dgreg (Calendar.gregorian_of_french d) Dfrench) | (None, _) -> match p_getenv conf.env (var ^ "_text") with [ Some txt -> let txt = strip_spaces (get var "text" conf.env) in if txt = "" then None else Some (Dtext txt) | _ -> None ] ] ; value print_date conf base lab var d = do { tag "table" "border=1" begin tag "tr" "align=left" begin stag "td" begin Wserver.wprint "%s" lab; end; let d = match d with [ Some (Dgreg d Dgregorian) -> Some d | Some (Dgreg d Djulian) -> Some (Calendar.julian_of_gregorian d) | Some (Dgreg d Dfrench) -> Some (Calendar.french_of_gregorian d) | Some (Dgreg d Dhebrew) -> Some (Calendar.hebrew_of_gregorian d) | _ -> None ] in tag "td" begin Wserver.wprint "%s\n" (transl_nth conf "year/month/day" 0); Wserver.wprint "\n" var (match d with [ Some {year = y} -> " value=" ^ string_of_int y | _ -> "" ]); Wserver.wprint "%s\n" (transl_nth conf "year/month/day" 1); Wserver.wprint "\n" var (match d with [ Some {month = m} when m <> 0 -> " value=" ^ string_of_int m | _ -> "" ]); Wserver.wprint "%s\n" (transl_nth conf "year/month/day" 2); Wserver.wprint "\n" var (match d with [ Some {day = d} when d <> 0 -> " value=" ^ string_of_int d | _ -> "" ]); end; tag "td" begin Wserver.wprint "... %s %s\n" (transl conf "or") (transl conf "text"); Wserver.wprint "\n" var (match d with [ Some (Dtext t) -> " value=\"" ^ quote_escaped t ^ "\"" | _ -> "" ]); end; end; end; tag "table" "border=1" begin tag "tr" "align=left" begin tag "td" begin Wserver.wprint "%s\n" (capitale (transl_nth conf "calendar/calendars" 0)); tag "select" "name=%s_cal" var begin Wserver.wprint "