~ubuntu-branches/ubuntu/trusty/lifelines/trusty

« back to all changes in this revision

Viewing changes to reports/cron.ll

  • Committer: Bazaar Package Importer
  • Author(s): Felipe Augusto van de Wiel (faw)
  • Date: 2007-08-14 00:02:04 UTC
  • mfrom: (1.1.4 upstream) (3.1.4 gutsy)
  • Revision ID: james.westby@ubuntu.com-20070814000204-mpv5faygl0dgq3qi
Tags: 3.0.61-1
* New upstream release. (Closes: #387856).
* Fixing documentation build problems also fixes FTBFS if built twice in a
  row. (Closes: #424543).
* Adding lynx as a build dependency. This is necessary to generate txt files
  from html, discovered while fixing #424543.
* Upstream fix: charset for gedcom file in unicode. (Closes: #396206).
* Upstream fim: updating documentation about desc-tex2. (Closes: #405501).
* Bumping Standards-Version to 3.7.2 without package changes.
* Dropping local debian patches added upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * @progname       cron.ll
3
 
 * @version        2.0
 
3
 * @version        4.0
4
4
 * @author         Stephen Dum
5
5
 * @category       
6
6
 * @output         HTML
9
9
Generate calendar of birth, death, marriage events arranged by the year, month 
10
10
and day that they occurred.  Generates a top level index by year, with actual
11
11
events stored in a separate html file for each decade.
12
 
Warning, this report requires lifelines version 3.0.27 or later.
13
12
Some properties must be set in your lifelines configuration file for this
14
13
report to run, see comments at beginning of the report for details.
15
14
 
 
15
Warning, this report requires lifelines version 3.0.50 or later.
 
16
 
16
17
         by Stephen Dum (stephen.dum@verizon.net)
17
18
         Version 1   March    2003  
18
 
         Version 2   November 2005
 
19
         Version 2   November 2005 Support privitizing data
 
20
         Version 3   December 2005 Do html char set encoding
 
21
         Version 4   June 2006 incorporated mods by Dave Eaton (dwe@arde.com) May 2006
19
22
 
20
23
This program was inspired by similar efforts by Mitch Blank (mitch@ctrpnt.com)
21
24
but without ever seeing the code he used to do a similar thing.
22
25
 
 
26
The code used in cron.ll is very similar to anniver.ll.  Other than the
 
27
sort order and print out details, the two programs share about 3/4 of their
 
28
code.
 
29
 
23
30
Before using, there are a few properties that need to be customized for your
24
31
own environment so add them to your .linesrc ( or for windows lines.cfg) file.
 
32
You can also set them on the command line (like -Ianniver.htmldir=/tmp/foo)
25
33
The properties that are looked up are:
26
34
   user.fullname -- name of the database owner
27
35
   user.email -- email address of the db owner
28
36
   cron.htmldir -- path to the directory to store results in
29
37
                     e.g. /home/joe/genealogy/html
30
 
                     (program expects a subdir in this directory with the name
31
 
                     of the database in it.)
32
 
   cron.backgroundimage -- path to the background image, no image if not defined.
 
38
                     (program expects a subdir in this directory with the name
 
39
                     of the database in it.)
 
40
   cron.backgroundimage -- path to the background image,
 
41
                 no image if not defined.
33
42
                 e.g. ../../image/crink.jpg
34
 
                 this places image at the same level as /home/joe/genealogy/html
 
43
                 this places image at the same level as /home/joe/genealogy/html
 
44
   privatization:  This report respects 2 levels of privatization
 
45
       1. if a record "RESN confidential" exists on an individual they are
 
46
          skipped (as this report is designed to be shared, this seems
 
47
          like a reasonable default)
 
48
       2. skip anyone estimated to be living
 
49
 
 
50
   History.
 
51
      Version 2 Add code to allow respecting privatized data.
 
52
      Version 3 switch from baptism() to get_baptism() for wider coverage
 
53
                use translation tables to convert data to properly 
 
54
                escaped html.  This is very codeset dependent.
 
55
     Version 4   added changes by Dave Eaton (dwe@arde.com)
 
56
         These were actually changes to anniver4, but merged here too.
 
57
         Added "firstyear" that events may be on the calendar
 
58
         Added "includedeath" check to drop deaths if those are not desired
 
59
         Added ability to generate report for descendants of more than one
 
60
             individual
 
61
         Added ability to generate report only for living people 
 
62
             (omitting confidential if desired)
35
63
*/
36
64
 
37
65
/* customization globals */
38
66
char_encoding("ASCII")
39
67
option("explicitvars")
40
68
 
41
 
global(base_filename)   /* where to store the results */
42
 
global(background)      /* path of background image relative to final html
43
 
                         * location, or "" */
44
 
global(hi_bg_color)     /* highlighted year background color */
45
 
global(lo_bg_color)     /* non-highlighted year background color */
 
69
global(base_filename)   /* where to store the results */
 
70
global(background)      /* path of background image relative to final html
 
71
                         * location, or "" */
 
72
global(hi_bg_color)     /* highlighted year background color */
 
73
global(lo_bg_color)     /* non-highlighted year background color */
46
74
 
47
75
global(db_owner)        /* name of database owner - from config file */
48
76
global(owner_email)     /* email of database owner - from config file */
49
 
global(privatize)       /* should we privatize the data */
 
77
global(justliving)      /* should we generate a report only for living people? */
 
78
global(privatize)       /* should we privatize the data 
 
79
                         * 0 = display all data
 
80
                         * 1 = skip confidential records
 
81
                         * 2 = skip confidential and living
 
82
                         */
50
83
global(withkey)         /* should we include key's in the output */
51
84
global(cutoff_year)     /* 100 years before today */
52
85
                        /* birth >= cutoff_year  is about 101 years,
53
 
                         * and we consider person living */
 
86
                         * and we consider person living */
 
87
 
 
88
global(firstyear)       /* earliest year for which entries should be included */
 
89
global(includedeath)    /* if set, then include the death events on the calendar */
54
90
 
55
91
global(month_name)      /* names of the months */
56
92
global(events)          /* list of events to print */
57
93
global(dates)           /* list of dates of the events */
 
94
global(keynames)        /* name(s) of the key individuals for this report */
58
95
 
59
96
proc main ()
60
97
{
69
106
    set(base_filename,concat(getproperty("cron.htmldir"),"/",database(),"/"))  
70
107
    if (not(test("d",base_filename))) {
71
108
        print("Error, property cron.htmldir=",base_filename,
72
 
              ", is not a directory,aborting\n")
73
 
        print("Please read comments at beginning of report about setting properties\n")
 
109
              ", is not a directory,aborting\n")
 
110
        print("Please read comments at beginning of report about setting properties\n")
74
111
        return()
75
112
    }
76
113
 
91
128
 
92
129
    extractdate(gettoday(),day,mon,cutoff_year)
93
130
    decr(cutoff_year,100)
 
131
    set(cs,getproperty("codeset"))
 
132
    if (eqstr(cs,"UTF-8")) {
 
133
        set(srccs,"UTF-8")
 
134
        set(dstcs,"UTF-8//html")
 
135
    } elsif (eqstr(cs,"ISO-8859-15")) {
 
136
        set(srccs,"ISO-8859-15//html")
 
137
        set(dstcs,"UTF-8")
 
138
    } else {
 
139
        print("\nDatabase codeset ",cs," not supported, exiting\n")
 
140
    }
94
141
 
95
142
    /* end of initialization of globals */
96
143
 
97
 
    getint(privatize,"Enter 1 to privitize data, 0 otherwise")
 
144
    getint(justliving,"Enter 1 to include only living people, 0 otherwise")
 
145
    if (justliving) {
 
146
        /* Default the choices which conflict with "justliving" */
 
147
        set(includedeath,0)
 
148
        /* We want living people, so see if we also want confidental */
 
149
        getint(noconfidential,"Enter 1 to omit confidential living people, 0 otherwise")
 
150
        if (noconfidential) {
 
151
            set(privatize,1)
 
152
        } else {
 
153
            set(privatize,0)
 
154
        }
 
155
    } else {
 
156
        getint(privatize,"\nPrivatization: 0 print all data; 1 skip confidential records; 2 skip confidential and living")
 
157
        getint(includedeath,"Enter 1 to include deaths on calendar, 0 otherwise")
 
158
    }
98
159
    getint(withkey,"Enter 1 to include keys, 0 otherwise")
99
 
    getindi(person,"Enter person to find descendants of (return for all)")
 
160
    getint(firstyear,"Enter oldest year to be on calendar, 0 for no limit")
 
161
    getindi(person,"Enter person for whom to find descendants (return for all)")
100
162
    indiset(thisgen)
101
163
    indiset(allgen)
102
164
    list(events)
103
165
    list(dates)
 
166
    list(keynames)
 
167
    set(firstpass,1)
104
168
    /* if a person is entered, the generated list of people include
105
169
     * person and spouse, and all the children of either
106
170
     * and then recursively the people, their spouses and all the children
107
171
     * thereof
108
172
    */
109
173
    if (person) {
110
 
        addtoset(thisgen, person, 0)
111
 
        addtoset(allgen, person, 0)
112
 
        print("Computing descendants ")
113
 
        set(thisgensize,1)
114
 
        set(gen,neg(1))
115
 
        while(thisgensize) {
116
 
            set(gen,add(gen,1))
117
 
            print(d(gen)," ")
118
 
            indiset(spouse)
119
 
            set(spouse,spouseset(thisgen))
120
 
            set(thisgen,childset(union(thisgen,spouse)))
121
 
            set(allgen,union(allgen,spouse))
122
 
            set(allgen,union(allgen,thisgen))
123
 
            set(thisgensize,lengthset(thisgen))
124
 
        }
125
 
        print (nl(), "Total of ",d(lengthset(allgen))," individuals",nl())
126
 
        forindiset(allgen,indi,val,i) {
127
 
            if (not(mod(i,100))) {
128
 
                print(".")
129
 
            }
130
 
            call add_indi(indi)
131
 
        }
 
174
        while (person) {
 
175
            addtoset(thisgen, person, 0)
 
176
            addtoset(allgen, person, 0)
 
177
            print("Computing descendants of ", name(person), " ")
 
178
            enqueue(keynames,concat(name(person)))
 
179
            set(thisgensize,1)
 
180
            set(gen,neg(1))
 
181
            while(thisgensize) {
 
182
                set(gen,add(gen,1))
 
183
                print("adding ",d(thisgensize)," individuals for generation ",d(gen),"\n")
 
184
                indiset(spouse)
 
185
                set(spouse,spouseset(thisgen))
 
186
                set(thisgen,childset(union(thisgen,spouse)))
 
187
                set(allgen,union(allgen,spouse))
 
188
                set(allgen,union(allgen,thisgen))
 
189
                set(thisgensize,length(thisgen))
 
190
                /* the following check prevents looping if the
 
191
                 * database has been corrupted and a parent is listed
 
192
                 * as a child of that parent, and diagnoses the fault
 
193
                 */
 
194
                if (eq(length(intersect(allgen,thisgen)),thisgensize)) {
 
195
                    set(thisgensize,0)
 
196
                    print("Warning child is listed as its own parent\n")
 
197
                    forindiset(thisgen,indi,val,i) {
 
198
                       print (name(indi)," ")
 
199
                    }
 
200
                    print("\n")
 
201
                }
 
202
            }
 
203
            if (firstpass) {
 
204
                print ("Total of ")
 
205
                set(firstpass,0)
 
206
            } else {
 
207
                print ("New total of ")
 
208
            }
 
209
            print (d(length(allgen))," individuals",nl())
 
210
            getindi(person,"Enter next person for whom to find descendants")
 
211
        }
 
212
        /* now generate list of events */
 
213
        forindiset(allgen,indi,val,i) {
 
214
            if (not(mod(i,100))) {
 
215
                print(".")
 
216
            }
 
217
            call add_indi(indi)
 
218
        }
 
219
        print("\n")
132
220
    } else {
133
 
        print("Traversing all individuals ")
 
221
        print("Traversing all individuals ")
134
222
        forindi (indi, val) {
135
 
            if (not(mod(val,100))) {
136
 
                print(".")
137
 
            }
138
 
            call add_indi(indi)
139
 
            set(max,val)
140
 
        }
141
 
        print (nl(), "Total of ",d(max)," individuals",nl())
 
223
            if (not(mod(val,100))) {
 
224
                print(".")
 
225
            }
 
226
            call add_indi(indi)
 
227
            set(max,val)
 
228
        }
 
229
        print (nl(), "Total of ",d(max)," individuals",nl())
142
230
    }
143
231
    print( d(length(dates))," events generated",nl())
144
232
    
157
245
    print( d(length(dates))," events",nl()) 
158
246
    while(length(dates)) {
159
247
        set(val,pop(dates))
160
 
        set(event,pop(events))
161
 
        set(year,div(val,10000))
162
 
        set(mon, mod(val,10000))
163
 
        set(day, mod(mon,100))
164
 
        set(mon, div(mon,100))
165
 
        set(decade, div(year,10))
166
 
        /* print(d(mon),"/",d(day),"/",d(year)," ", event, nl())  debug */
 
248
        set(event,pop(events))
 
249
        set(year,div(val,10000))
 
250
        set(mon, mod(val,10000))
 
251
        set(day, mod(mon,100))
 
252
        set(mon, div(mon,100))
 
253
        set(decade, div(year,10))
 
254
        /* print(d(mon),"/",d(day),"/",d(year)," ", event, nl())  debug */
167
255
 
168
 
        if (ne(lastdecade,decade)) {
169
 
            if (ne(lastdecade,-1)) {
170
 
                if (in_year) {
171
 
                    "</table>\n"
172
 
                    set(in_year,0)
173
 
                }
174
 
                call write_tail()
175
 
            }
176
 
            call openfile(concat("dec",d(decade)),concat(d(mul(decade,10)),
177
 
                         " - ",d(add(mul(decade,10),9))," Events"))
178
 
            set(lastdecade,decade)
179
 
        }
180
 
        if (ne(lastyear,year)) {
181
 
            if (in_year) {
182
 
                "</table>\n"
183
 
            }
184
 
            "<p><a name=" d(year) "><h2>" d(year) "</h2></a>" nl()
185
 
            push(yearmask,year)
186
 
            "<table>" nl()
187
 
            set(in_year,1)
188
 
            set(lastyear,year)
189
 
        }
190
 
        if (mon) {
191
 
            if (day) {
192
 
                set(title,concat(getel(month_name,mon)," ",d(day)))
193
 
            } else {
194
 
                set(title,getel(month_name,mon))
195
 
            }
196
 
        } else {
197
 
            if (day) {
198
 
                set(title,d(day))
199
 
            } else {
200
 
                set(title,"")
201
 
            }
202
 
        }
203
 
        "<tr>\n<td width=\"150\" valign=top align=left>"
204
 
        "<font size=4><b>" title "</b></font>\n"
205
 
        "<td><font size=4>" event "</font></td>\n"
 
256
        if (ne(lastdecade,decade)) {
 
257
            if (ne(lastdecade,-1)) {
 
258
                if (in_year) {
 
259
                    "</table>\n"
 
260
                    set(in_year,0)
 
261
                }
 
262
                call write_tail()
 
263
            }
 
264
            call openfile(concat("dec",d(decade)),concat(d(mul(decade,10)),
 
265
                         " - ",d(add(mul(decade,10),9))," Events"))
 
266
            set(lastdecade,decade)
 
267
        }
 
268
        if (ne(lastyear,year)) {
 
269
            if (in_year) {
 
270
                "</table>\n"
 
271
            }
 
272
            "<p><a name=" d(year) "><h2>" d(year) "</h2></a>" nl()
 
273
            push(yearmask,year)
 
274
            "<table>" nl()
 
275
            set(in_year,1)
 
276
            set(lastyear,year)
 
277
        }
 
278
        if (mon) {
 
279
            if (day) {
 
280
                set(title,concat(getel(month_name,mon)," ",d(day)))
 
281
            } else {
 
282
                set(title,getel(month_name,mon))
 
283
            }
 
284
        } else {
 
285
            if (day) {
 
286
                set(title,d(day))
 
287
            } else {
 
288
                set(title,"")
 
289
            }
 
290
        }
 
291
        "<tr>\n<td width=\"150\" valign=top align=left>"
 
292
        "<font size=4><b>" title "</b></font>\n"
 
293
        "<td><font size=4>" 
 
294
        if (srccs) {
 
295
            convertcode(event,srccs,dstcs)
 
296
        } else {
 
297
            event
 
298
        }
 
299
        "</font></td>\n"
206
300
    }
207
301
    if (in_year) {
208
 
        "</table>\n"
 
302
        "</table>\n"
209
303
    }
210
304
    call write_tail()
211
305
 
213
307
 
214
308
    call openfile("cron","Chronological Event Calendar")
215
309
    "This calendar indexes events by the year in which they occurred.\n"
216
 
        "<P>Click on the year to see the events that occurred in that year.\n"
217
 
        "<hr>\n"
218
 
        "<table border=4 width=\"99%\">\n"
 
310
        "<P>Click on the year to see the events that occurred in that year.\n"
 
311
        "<hr>\n"
 
312
        "<table border=4 width=\"99%\">\n"
219
313
 
220
314
    /* The calendar is arranged with 10 years across. */
221
315
 
225
319
    set(minyear,getel(yearmask,1))
226
320
    set(maxyear,getel(yearmask,0))
227
321
    forlist(yearmask,this_year,cnt) {
228
 
        while(le(cur_year,this_year)) {
229
 
            if (eq(mod(cur_year,10),0)) {
230
 
                /* print("processing decade ",d(decade),nl()) / * debug */
231
 
                "<tr>" nl()
232
 
            }
233
 
            if (eq(cur_year,this_year)) {
234
 
                /* print year with a link to year page */
235
 
                "<td bgcolor=" hi_bg_color
236
 
                " align=center><font size=4><a href=\""
 
322
        while(le(cur_year,this_year)) {
 
323
            if (eq(mod(cur_year,10),0)) {
 
324
                /* print("processing decade ",d(decade),nl()) / * debug */
 
325
                "<tr>" nl()
 
326
            }
 
327
            if (eq(cur_year,this_year)) {
 
328
                /* print year with a link to year page */
 
329
                "<td bgcolor=" hi_bg_color
 
330
                " align=center><font size=4><a href=\""
237
331
                "dec" d(decade) ".html#" d(cur_year) "\">" 
238
 
                d(cur_year) "</a>\n</font></td>\n"
239
 
            } else {
240
 
                if (or(lt(cur_year,minyear),gt(cur_year,maxyear))) {
241
 
                    /* blank out year */
242
 
                    "<td bgcolor=" lo_bg_color
243
 
                    " align=center><font size=4></font></td>" nl()
244
 
                } else {
245
 
                    /* print year without a link to year page */
246
 
                    "<td bgcolor=" lo_bg_color
 
332
                d(cur_year) "</a>\n</font></td>\n"
 
333
            } else {
 
334
                if (or(lt(cur_year,minyear),gt(cur_year,maxyear))) {
 
335
                    /* blank out year */
 
336
                    "<td bgcolor=" lo_bg_color
 
337
                    " align=center><font size=4></font></td>" nl()
 
338
                } else {
 
339
                    /* print year without a link to year page */
 
340
                    "<td bgcolor=" lo_bg_color
247
341
                    " align=center><font size=4>" d(cur_year) "</font></td>" nl()
248
 
                }
249
 
            }
250
 
            incr(cur_year)
251
 
            if (eq(mod(cur_year,10),0)) {
252
 
                "</tr>" nl()
253
 
                incr(decade)
254
 
            }
255
 
        }
 
342
                }
 
343
            }
 
344
            incr(cur_year)
 
345
            if (eq(mod(cur_year,10),0)) {
 
346
                "</tr>" nl()
 
347
                incr(decade)
 
348
            }
 
349
        }
256
350
    }
257
351
 
258
352
    "</table>\n"
267
361
  print("Writing ", filename, "\n")
268
362
  newfile(filename, 0)
269
363
 
270
 
  "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
 
364
  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
271
365
  "<!DOCTYPE html public \"-//W3C//DTD HTML 4.01 Transitional//EN\" >\n"
272
366
  "<html>\n<head>\n"
 
367
   "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n"
273
368
  "<title> " title " </title>\n"
274
369
  "<style type=\"text/css\">\n"
275
370
  "p.hindent { margin-top: 0.2em; margin-bottom:0em;\n"
312
407
proc add_indi(indi) {
313
408
    set(birth_type,0)
314
409
    if (birth,birth(indi)) {
315
 
        set(birth,get_date(birth))
316
 
        set(birth_type," born")
317
 
    } elsif (birth, baptism(indi)) {
318
 
        set(birth,get_date(birth))
319
 
        set(birth_type," baptized")
 
410
        set(birth,get_date(birth))
 
411
        set(birth_type," born")
 
412
    } elsif (birth, get_baptism(indi)) {
 
413
        set(birth,get_date(birth))
 
414
        set(birth_type," baptized")
320
415
    }
321
416
    set(death_type,0)
322
417
    if (death,death(indi)) {
323
 
        set(death,get_date(death))
324
 
        set(death_type," died")
 
418
        set(death,get_date(death))
 
419
        set(death_type," died")
325
420
    } elsif (death, burial(indi)) {
326
 
        set(death,get_date(death))
 
421
        set(death,get_date(death))
327
422
        set(death_type," buried")
328
423
    }
 
424
    /* skip confidential records and living people */
329
425
    if (privatize) {
330
 
        /* skip confidential or living people */
331
 
        if (confidential(indi)) { return() }
332
 
        /* living - birth, no death, and birth < 101 years ago */
333
 
        if (and(birth,not(death))) {
334
 
            if (ge(div(birth,10000),cutoff_year)) { return()}
335
 
        }
 
426
        if (confidential(indi)) { return() }
 
427
 
 
428
        /* living - birth, no death, and birth < 101 years ago */
 
429
        if (and(ge(privatize,2),birth,not(death))) {
 
430
            if (ge(div(birth,10000),cutoff_year)) { return()}
 
431
        }
336
432
    }
337
433
    if (birth) {
338
 
        if (withkey) {
339
 
            enqueue(events,concat(name(indi),"(",key(indi),")",birth_type))
340
 
        } else {
341
 
            enqueue(events,concat(name(indi),birth_type))
342
 
        }
343
 
        enqueue(dates,birth)
 
434
        /* Make certain that if we only want living people that this is 
 
435
           (or at least may be) */
 
436
        if (not(or(and(justliving,death),and(justliving,lt(mod(birth,10000),cutoff_year))))) {
 
437
                if (withkey) {
 
438
                    enqueue(events,concat(name(indi),"(",key(indi),")",birth_type))
 
439
                } else {
 
440
                    enqueue(events,concat(name(indi),birth_type))
 
441
                }
 
442
                enqueue(dates,birth)
 
443
        }
344
444
    }
345
 
    if (death) {
346
 
        if (withkey) {
347
 
            enqueue(events,concat(name(indi),"(",key(indi),")",death_type))
348
 
        } else {
349
 
            enqueue(events,concat(name(indi),death_type))
350
 
        }
351
 
        enqueue(dates,death)
 
445
    if (and(includedeath,death)) {
 
446
        if (withkey) {
 
447
                enqueue(events,concat(name(indi),"(",key(indi),")",death_type))
 
448
        } else {
 
449
                enqueue(events,concat(name(indi),death_type))
 
450
        }
 
451
        enqueue(dates,death)
352
452
    }
353
453
 
354
454
    families(indi,famly, spouse, cnt) {
355
 
        if (privatize) {
356
 
            /* skip confidential families */
357
 
            if (confidential(famly)) { return() }
358
 
        }
359
 
        /* to avoid duplication, only enter data 
360
 
         * if indi is male, or there is no spouse
361
 
         */
362
 
        if (or(male(indi),not(spouse))) {
363
 
            fornodes(fnode(famly), node) {
364
 
                if(eqstr(tag(node),"MARR")) {
365
 
                    if (spouse) {
366
 
                        set(spo,concat(" and ",name(spouse)," married"))
367
 
                    } else {
368
 
                        set(spo," married")
369
 
                    }
370
 
                    set(marr,get_date(node))
371
 
                    if (marr) {
372
 
                        if (withkey) {
373
 
                            enqueue(events,concat(name(indi),spo,
374
 
                                    "(",key(indi),",",key(spouse),")"))
375
 
                        } else {
376
 
                            enqueue(events,concat(name(indi),spo))
377
 
                        }
378
 
                        enqueue(dates,marr)
379
 
                    }
380
 
                }
381
 
            }
382
 
        }
 
455
        /* skip confidential families */
 
456
        if (confidential(famly)) { continue() }
 
457
        if (and(privatize,spouse)) {
 
458
            if (confidential(spouse)) { continue() }
 
459
        }
 
460
        if (justliving) {
 
461
            /* make sure the person is living: no death, birth and 
 
462
               birth < 101 years ago */
 
463
            /* Nope, we know they have died */
 
464
            if (death) { return() }
 
465
            if (birth) {
 
466
                /* Nope, estimated they would be too old now */
 
467
                if (lt(mod(birth,10000),cutoff_year)) { return() }
 
468
            }
 
469
        }
 
470
        /* living - birth, no death, and birth < 101 years ago */
 
471
        if (ge(privatize,2)) {
 
472
            if (and(birth(spouse),not(death(spouse)))) {
 
473
                if (ge(mod(get_date(birth(spouse)),10000),cutoff_year)) { continue()}
 
474
            }
 
475
        }
 
476
        /* to avoid duplication, only enter data 
 
477
         * if indi is male, or there is no spouse
 
478
         */
 
479
        if (or(male(indi),not(spouse))) {
 
480
            fornodes(fnode(famly), node) {
 
481
                if(eqstr(tag(node),"MARR")) {
 
482
                    if (spouse) {
 
483
                        set(names,concat(name(indi)," and ",name(spouse)))
 
484
                        set(keys,concat("(",key(indi),",",key(spouse),")"))
 
485
                    } else {
 
486
                        set(names,name(indi))
 
487
                        set(keys,concat("(",key(indi),")"))
 
488
                    }
 
489
                    set(marr,get_date(node))
 
490
                    if (marr) {
 
491
                        /* Make sure date is plausible for living or that we don't care */
 
492
                        if (or(not(justliving),ge(mod(marr,10000),cutoff_year))) {
 
493
                            if (withkey) {
 
494
                                enqueue(events,concat(names,keys," married"))
 
495
                            } else {
 
496
                                enqueue(events,concat(names," married"))
 
497
                            }
 
498
                            enqueue(dates,marr)
 
499
                        }
 
500
                    }
 
501
                }
 
502
            }
 
503
        }
383
504
    }
384
505
}
385
506
 
392
513
{
393
514
    extractdate(node,day,mon,yr)
394
515
    if (yr) {
395
 
        return(add(mul(add(mul(yr,100),mon),100),day))
 
516
        return(add(mul(add(mul(yr,100),mon),100),day))
396
517
    }
397
518
    return(0)
398
519
}
401
522
{
402
523
    fornodes(n,node) {
403
524
        if (eqstr(tag(node),"RESN")) {
404
 
            if (eqstr(value(node),"confidential")) {
405
 
                return(1)
406
 
            }
407
 
        }
 
525
            if (eqstr(value(node),"confidential")) {
 
526
                return(1)
 
527
            }
 
528
        }
 
529
    }
 
530
    return(0)
 
531
}
 
532
func get_baptism(ind)
 
533
{
 
534
    fornodes(ind,node) {
 
535
        if (index(" BAPM BAPL CHR CHRA ",concat(" ",upper(tag(node))," "),1)) {
 
536
            return(node)
 
537
        }
408
538
    }
409
539
    return(0)
410
540
}