(* 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
\n";
html_li conf;
Wserver.wprint "%s:\n" (capitale (transl conf "before"));
Wserver.wprint "\n";
tag "ul" begin
Array.iter
(fun ip ->
let p = poi base ip in
do {
html_li conf;
if p.surname = fath.surname then print_first_name conf base p
else print_someone conf base p;
Wserver.wprint "%s" (Date.short_dates_text conf base p);
Wserver.wprint "\n"
})
before;
end;
html_li conf;
Wserver.wprint "%s:\n" (capitale (transl conf "after"));
Wserver.wprint "\n";
tag "ul" begin
Array.iter
(fun ip ->
let p = poi base ip in
do {
html_li conf;
if p.surname = fath.surname then
print_first_name_ref conf base p
else print_someone_ref conf base p;
Wserver.wprint "%s" (Date.short_dates_text conf base p);
Wserver.wprint "\n"
})
des.children;
end;
Wserver.wprint "
"
}
| 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 "
\n";
html_li conf;
print_first_name_strong conf base elder;
Wserver.wprint "%s" (Date.short_dates_text conf base elder);
Wserver.wprint "\n";
html_li conf;
print_first_name_strong conf base x;
Wserver.wprint "%s" (Date.short_dates_text conf base x);
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 "