4
* @author J.F. Chandler
9
displays the descendancy line(s) from one person to another.
10
This program assumes no individual has more than one set of parents.
12
Algorithm partly borrowed from TTW's cousins program.
14
Version 1 - 1998 Apr 22 - J.F. Chandler
16
This program requires version 3 of LifeLines.
19
global(link1) /* table of links back one person */
20
global(link2) /* table of alternate links */
21
global(elist) /* list of chain ends */
22
global(dots) /* person counter */
25
getindimsg(from,"Which ancestor?")
28
getindimsg(to,"Which descendant?")
30
if(not(and(from,to))) {
34
set(fkey,save(key(from)))
35
set(tkey,save(key(to)))
36
"Descendancy line from " name(indi(fkey)) "\nto " name(indi(tkey)) ":\n"
37
print("Searching for the line(s) from:\n",name(from)," to ",name(to))
38
print(".\n\nThis may take a while -- ")
39
print("each dot is 25 persons considered.\n")
50
/* Link the ancestor to self (unique marker), and add as the first
51
entry in the list of chain ends. A "zero" person in the list marks
52
the end of a generation. */
54
insert(link1,fkey,fkey)
58
/* Iterate through the list of chain ends, removing them one by one;
59
link their children back to them; add the children to the chain end
60
list; check each iteration to see if the target person has been found
61
through both parents; if so quit the iteration; also quit three
62
generations after finding through either parent. */
64
while(gt(length(elist),1)) {
65
set(key,dequeue(elist))
68
if(eq(gen,maxgen)) { break() }
73
families(indi,fam,sp,n1) {
74
children(fam,child,n2) {
75
call include(key,child)
79
if(lookup(link1,tkey)) {
81
set(maxgen,add(3,gen))
83
} elsif(lookup(link2,tkey)) { break() }
86
/* Quit if the "from" is not an ancestor of the "to" person. */
89
print("\nThere is no such line.")
90
"There is no such line.\n"
95
"\nWorking back:\n\n1. " call do_person(indi(tkey))
96
call printrest(tkey,gen)
99
/* Recursively print the rest of the line back to the source.
100
If the current person is linked through both parents, also print
101
the alternate line starting from here. */
103
proc printrest(key,gen) {
105
set(new,lookup(link1,key))
106
if(eq(0,strcmp(key,new))) { return() }
107
d(gen) ". " call do_person(father(indi(key)))
108
" & " call do_person(mother(indi(key)))
109
if(alt,save(lookup(link2,key))) { "* " } /* mark a branch point */
110
call printrest(new,gen)
113
call printrest(alt,gen)
116
/* Link a new child (indi) back to a parent (key).
117
If the new child has already been linked once, use alternate table.
118
A truly new child is added to the list of chain ends */
120
proc include(key,indi) {
122
set(dots,add(dots,1))
128
set(new,save(key(indi)))
129
if(lookup(link1,key(indi))) {
130
insert(link2,new,key)
132
insert(link1,new,key)
136
/* Print name and dates for a given person */
141
if(not(e)) {set(e,baptism(p))}
145
if(not(e)) {set(e,burial(p))}