Wikipedysta:Jurekj
Z Wikipedii
Spis treści |
[edytuj] Generowanie drzew genealogicznych
[edytuj] Link do strony
Formularz na stronie "http://linux.dti.zptr.com.pl/wiki" umożliwia wygenerowanie kodu drzewa genealogicznego (tabela w HTML-u) do wklejenia do hasła w Wikipedii na podstawie danych w opisanym niżej formacie.
[edytuj] Format danych
W dyskusji do hasła umieszczamy dane do wygenerowania drzewa w formacie: id::klucz::wartość
gdzie:
id - nr identyfikacyjny osoby mającej się pojawić w drzewie, od osoby z id=1 rozpoczyna się rysunek drzewa. Kolejne osoby nie muszą mieć kolejnych numerów, dla każdego użytego numeru musi być jednak podany wiersz z kluczem: name. Kolejność wierszy też nie ma znaczenia.
klucz - w tym mamencie dopuszczalne są następujące klucze:
* name - wymagany, wartość definiuje nazwę pod jaką pojawi się osoba w drzewie * item - opcjonalny, wartość definiuje hasło w Wikipedii pod którym dana osoba występuje * children - opcjonalny, wartość to lista rozdzielonych przecinkami id potomków danej osoby * spouses - opcjonalny, wartość to lista rozdzielonych przecinkami id małżonków danej osoby
dla przykładu poniżej takie dane do drzewa genealogicznego Pompejuszy:
1::name::Gnejusz Pompejusz Strabon 1::item::Pompejusze#Gnejusz Pompejusz Strabon 1::children::2 2::item::Pompejusz 2::name::Gnejusz Pompejusz Wielki 2::children::3,4,5 2::spouses::6,7,8,9,10 3::item::Pompejusze#Gnejusz Pompejusz Młodszy 3::name::Gnejusz Pompejusz Młodszy 3::spouses::11 4::item::Pompejusze#Sekstus Pompejusz 4::name::Sekstus Pompejusz 4::spouses::12 5::item::Pompejusze#Pompeja 5::name::Pompeja 5::children::15 5::spouses::13,14 6::name::Antistia 7::name::Emilia c. Marka Emiliusza Skaura 8::name::Mucia Tercja c. Kwintusa Muciusza Scewoli 9::name::Julia c. Cezara 10::name::Cecylia Metella Kornelia 11::name::Klaudia c. Appiusza Klaudiusza Pulchra 12::name::Skrybonia II 12::item::Skryboniusz Libon#Skrybonia II 13::name::Faustus Korneliusz Sulla Feliks 14::name::Lucjusz Korneliusz Cynna 14::item::Korneliusz Cynna#Lucjusz Korneliusz Cynna k.32 15::item::Korneliusz Cynna#Kornelia Pompeja Magna 15::name::Pompeja Kornelia 15::spouses::16 16::name::Skryboniusz III 16::item::Skryboniusz Libon#Lucjusz Skryboniusz Libon III
Dane kopiujemy do pliku "data.txt" i umieszczmy w tym samym katalogu co skrypt "gen_tab". Skrypt czyta ten plik i na jego podstawie generuje drzewo genealogiczne jako tabelę w kodzie HTML wysyłaną na standardowe wyjście. Tabelę tę można wkleić do hasła w Wikipedii. Aktualna wersję skryptu udostępniam i proszę o uwagi.Jurekj 21:06, 1 lis 2005 (CET)
[edytuj] skrypt "gen_tab"
#!/usr/bin/perl my $file = "data.txt"; my (@person,@item,@tree,@atr) = (); my @min = (0,0,0,0,0,0,0); my ($max_col,$max_line)=(); # rozmiary tablicy my ($id,$sex,$id_father,$id_mother,$nr_of_chidren,$list_of_children,$name,$id_item) = (); my %links = (); my %link_up = (); my %link_down = (); $start = 1 if not defined($start); &graph_def; &read_persons; &create_item($start,0,1); print "<TABLE cellspacing=\"1\" style=\"font-size: small;\">\n"; foreach my $id (@item) { $ld=scalar(@{$$id{'list_of_children_item'} } ); if ($ld == 0){ } elsif ($ld == 1) { $l1 = $$id{'line'}; $l2 = $item[$$id{'list_of_children_item'}[0]]{'line'}; if ($l1 == $l2) { $branch[$$id{'col'}][$$id{'line'}] = '14'; } else { print "error l1=$l1 l2=$l2 \n"; exit; } } else { $l1 = $item[$$id{'list_of_children_item'}[0]]{'line'}; $l2 = $item[$$id{'list_of_children_item'}[-1]]{'line'}; $branch[$$id{'col'}][$l1] = '34'; $branch[$$id{'col'}][$l2] = '24'; for ($i=$l1+1; $i < $l2; $i++) { $branch[$$id{'col'}][$i] = '23'; } for ($i=1; $i < $ld-1; $i++) { $l = $item[$$id{'list_of_children_item'}[$i]]{'line'}; $branch[$$id{'col'}][$l] = '234'; } } if ($ld == 1 ) { $branch[$$id{'col'}][$$id{'line'}] = '14'; } elsif ($ld > 0 ) { if ($branch[$$id{'col'}][$$id{'line'}] eq '234') { $branch[$$id{'col'}][$$id{'line'}] = '1234'; } elsif ($branch[$$id{'col'}][$$id{'line'}] eq '34') { $branch[$$id{'col'}][$$id{'line'}] = '134'; } elsif ($branch[$$id{'col'}][$$id{'line'}] eq '24') { $branch[$$id{'col'}][$$id{'line'}] = '124'; } else { $branch[$$id{'col'}][$$id{'line'}] = '123'; } } $id_per = $$id{'id'}; if (defined ($person[$id_per]{'item'})) { $per = "[[$person[$id_per]{'item'}|$person[$id_per]{'name'}]]"; } else { $per = "$person[$id_per]{'name'}"; } if (defined ($person[$id_per]{'nr_of_spouses'})) { $per.="<table style=\"font-size: x-small; font-style: italic; font-weight: normal;\">"; foreach my $id_spouse (@{$person[$id_per]{'list_of_spouses'}}) { if (defined $person[$id_spouse]{'item'}) { $spouse = "[[$person[$id_spouse]{'item'}|$person[$id_spouse]{'name'}]]"; } else { $spouse = "$person[$id_spouse]{'name'}"; } $per.="<tr><td>•$spouse</td></tr>" ; } $per.="</table>"; } $tree[$$id{'col'}][$$id{'line'}]=$per; } for (my $i=1;$i<$max_col+1;$i++) { print "<TR>\n"; for (my $j=1;$j<$max_line+1;$j++) { if (defined ($tree[$i][$j])) { print "<td colspan=2 style=\"border-style: outset; border-width: 3px;\">\n"; print $tree[$i][$j]; print "</TD>\n"; } else { print "<td colspan=2 style=\"border_style: none;\">\n"; print "</TD>\n"; } } print "</TR>\n"; print "<TR>\n"; for (my $j=1;$j<$max_line+1;$j++) { if (defined ($branch[$i][$j])) { print $link_up{$branch[$i][$j]}; } else { print "<td colspan=2 style=\"border_style: none;\">\n"; print "</TD>\n"; } } print "</TR>\n"; print "<TR>\n"; for (my $j=1;$j<$max_line+1;$j++) { if (defined ($branch[$i][$j])) { print $link_down{$branch[$i][$j]}; } else { print "<td colspan=2 style=\"border_style: none;\">\n"; print "</TD>\n"; } } print "</TR>\n"; } print "</TABLE>\n"; exit; sub read_persons { open(IN,"$file" ) or die "I cannot open $file\n"; while (<IN>) { chomp; next if /^#/; my ($id,$key,$value) = split(/::/); if ($key eq 'children') { $person[$id]{'list_of_children'} = [ split(/,/,$value) ]; $person[$id]{'nr_of_children'} = scalar(@{$person[$id]{'list_of_children'}}); } elsif ($key eq 'spouses') { $person[$id]{'list_of_spouses'} = [ split(/,/,$value) ]; $person[$id]{'nr_of_spouses'} = scalar(@{$person[$id]{'list_of_spouses'}}); } elsif ($key eq 'name') { $person[$id]{'name'} = $value; } elsif ($key eq 'item') { $person[$id]{'item'} = $value; } else { print "error in line $. of file $file \n"; exit; } } close IN; } sub create_item { my ($id,$item_father,$col) = @_; my $item_my = ++$id_item; my $max = 0; my $lineinherit = 0; $item[$item_my]{'id'} = $id; $item[$item_my]{'col'} = $col; $item[$item_my]{'list_of_children_item'} = []; if ($item_father>0) { push @{ $item[$item_father]{'list_of_children_item'}}, $item_my; $lineinherit = $item[$item_father]{'line'} - inthalf($person[$item[$item_father]{'id'}]{'nr_of_children'}); } else { my $lineinherit = 1; } if ( $lineinherit > $min[$col]) { $item[$item_my]{'line'} = $lineinherit; } else { $item[$item_my]{'line'} = $min[$col] +1; } $min[$col] = $item[$item_my]{'line'}; if ( $person[$id]{'nr_of_children'} > 0 ) { foreach my $child (@{$person[$id]{'list_of_children'} } ) { create_item ($child,$item_my,$col+1) ; } my $first_child = $item[$item_my]{'list_of_children_item'}[0]; my $last_child = $item[$item_my]{'list_of_children_item'}[-1]; my $newline = linehalf($item[$first_child]{'line'},$item[$last_child]{'line'}); $item[$item_my]{'line'} = $newline if ($newline>$item[$item_my]{'line'}); $min[$col] = $item[$item_my]{'line'}; } $max_line = $item[$item_my]{'line'} if $item[$item_my]{'line'} > $max_line; $max_col = $item[$item_my]{'col'} if $item[$item_my]{'col'} > $max_col; } sub inthalf { my ($left) = @_; if ($left > 1) { return ($left - ($left % 2 )) / 2; } else { return 0; } } sub linehalf { my ($min,$max) = @_; return ($min + inthalf($max - $min) ); } sub graph_def { my %links_data = ( "134" =>["r" ,"lb","r" ,"lt"], "123" =>["rb","lb","t" ,"t" ], "34" =>["nn","b" ,"r" ,"lt"], "14" =>["r" ,"l" ,"r" ,"l" ], "124" =>["rb","l" ,"rt","l" ], "1234"=>["rb","lb","rt","lt"], "13" =>["r" ,"lb","nn","t" ], "23" =>["b" ,"b" ,"t" ,"t" ], "234" =>["b" ,"b" ,"rt","lt"], "24" =>["b" ,"nn" ,"rt","l"], ); my %style = ( 'r' => 'border-right-style: solid; height: 50%; border-width: thin;', 'lb' => 'border-bottom-style: solid; border-left-style: solid; border-width: thin; height: 50%;', 'lt' => 'border-top-style: solid; border-left-style: solid; border-width: thin; height: 50%;', 'rb' => 'border-bottom-style: solid; border-right-style: solid; border-width: thin; height: 50%;', 't' => 'border-top-style: solid; border-width: thin; height: 50%;', 'nn' => 'border-width: thin; height: 50%;', 'b' => 'border-bottom-style: solid; border-width: thin; height: 50%;', 'l' => 'border-left-style: solid; border-width: thin; height: 50%;', 'rt' => 'border-top-style: solid; border-right-style: solid; border-width: thin; height: 50%;', ); foreach $link (keys %links_data) { $links{$link} = "<table style=\"border-style:none\" cellspacing=\"0\"> <tr> <td width=25 class=\"$links_data{$link}[0]\"> <br> </td> <td width=25 class=\"$links_data{$link}[1]\"> </td> </tr> <tr> <td class=\"$links_data{$link}[2]\">\ </td> <td class=\"$links_data{$link}[3]\">\ </td> </tr> </table>"; $link_up{$link} = "<td width=25 style=\"$style{$links_data{$link}[0]}\"> <br> </td> <td width=25 style=\"$style{$links_data{$link}[1]}\"> </td>"; $link_down{$link} = "<td style=\"$style{$links_data{$link}[2]}\">\ </td> <td style=\"$style{$links_data{$link}[3]}\">\ </td>"; } }