1/* 2 * @progname BW_descendants.ll 3 * @version 1.00 4 * @author Birger Wathne 5 * @category 6 * @output Text 7 * @description 8 * List successors with notes 9 10BW_descendants - a LifeLines report by Birger Wathne (Birger.Wathne@sdata.no) 11 12Version 1.00 13This program partially based on code by Brad Frecker and Dick Knowles. 14Suggestions and comments welcome. 15 16 17Output sample at bottom of this source file. 18 19This report generates a list of successors of the given person. For each 20successor and its spouse(s), all level 1 notes are listed. 21 22The report asks for some parameters: 23- Number of generations to include (0 gives all) 24- Amount of output for spouse's other families 25 0 - Only list the main person's marriages. Don't even mention 26 the fact that the spouse(s) have had other relationships. 27 1 - Print a one-line summary for each of the spouse's other 28 relationships (number of children, spouses name, etc) 29 2 - Print the one-liner from option 1, plus a full listing of 30 all stepchildren (not recursive) 31- Output type 32 0 - Text. Plain ascii output (like the sample) 33 1 - roff. Not finished, as I don't have an 8-bit clean roff. 34 If someone wants this, please finish it, and send me the code. 35 2 - HTML. This output uses <TABLE> tags, so you need HTML 3.0 support. 36 Uses bold fonts, etc. Nice.... 37- Language for generated text. The header, and all those small words 38 used in the output can be generated in the language you have your 39 data. Makes it look more natural. If you add new languages, please tell me. 40*/ 41 42global(strings) 43global(outputtype) 44global(true) 45global(false) 46 47func init_strings(language) { 48 if ( eq( language, 0)) { 49 insert(strings, "Header", "Successors of") 50 insert(strings, "Headerdate", "Date") 51 insert(strings, "Born", "Born") 52 insert(strings, "Dead", "Dead") 53 insert(strings, "Married", "Married") 54 insert(strings, "Relationship", "Relationship") 55 insert(strings, "with", "with") 56 insert(strings, "unknownspouse", "unknown spouse") 57 insert(strings, "descendants", "descendants") 58 insert(strings, "generations", "generations") 59 insert(strings, "children", "children") 60 insert(strings, "had", "had") 61 insert(strings, "all", "all") 62 insert(strings, "Notesfor", "Notes for") 63 64 return(0) 65 } 66 67 if ( eq( language, 1)) { 68 insert(strings, "Header", "Etterkommere etter") 69 insert(strings, "Headerdate", "Dato") 70 insert(strings, "Born", "F�dt") 71 insert(strings, "Dead", "D�d") 72 insert(strings, "Married", "Gift") 73 insert(strings, "Relationship", "Forhold") 74 insert(strings, "with", "med") 75 insert(strings, "unknownspouse", "ukjent ektefelle") 76 insert(strings, "descendants", "etterkommere") 77 insert(strings, "generations", "generasjoner") 78 insert(strings, "children", "barn") 79 insert(strings, "had", "hadde") 80 insert(strings, "all", "alle") 81 insert(strings, "Notesfor", "Notater for") 82 83 return(0) 84 } 85 86 return(1) 87} 88 89 90proc main () { 91 table(strings) 92 93 set(true, 1) 94 set(false, 0) 95 96 dayformat(0) 97 monthformat(4) 98 dateformat(0) 99 100 getindi(indi) 101 102 getintmsg (generation_count, "How many generations (0 for all)?") 103 if ( lt( generation_count, 0)) { 104 print("Illegal number of generations") 105 return() 106 } 107 108 getintmsg ( 109 spousefamilies, 110 "How much output for spouse's other families (0=none, 1=summary, 2=list children)?" 111 ) 112 if ( or( lt( spousefamilies, 0), gt( spousefamilies, 2))) { 113 print("Illegal answer") 114 return() 115 } 116 117 getintmsg(outputtype, "Output type (0=TEXT, 1=ROFF, 2=HTML)?") 118 if ( or( lt( outputtype, 0), gt( outputtype, 2))) { 119 print("Illegal output type") 120 return() 121 } 122 123 124 getintmsg( 125 language, 126 "Language for generated text (0=English, 1=Norwegian)?" 127 ) 128 if ( ne( init_strings(language), 0)) { 129 print("Couldn't initialize string table to selected language") 130 return() 131 } 132 133 output_init() 134 /* Headers */ 135 if ( eq( generation_count, 0)) { 136 output_header1 ( 137 concat( 138 lookup( strings, "Header")," ", 139 name(indi), " ", 140 lookup( strings, "with"), " ", 141 lookup( strings, "all"), " ", 142 lookup( strings, "descendants") 143 ) 144 ) 145 } else { 146 if ( eq( generation_count, 1)) { 147 output_header1 ( 148 concat( 149 lookup( strings, "Header"), " ", 150 name(indi), " " 151 ) 152 ) 153 } else { 154 output_header1 ( 155 concat( 156 lookup( strings, "Header"), " ", 157 name(indi), " ", 158 lookup( strings, "with"), " ", 159 d(sub(generation_count,1)), " ", 160 lookup( strings, "generations"), " ", 161 lookup( strings, "descendants") 162 ) 163 ) 164 } 165 } 166 nl() nl() 167 168 output_header2( 169 concat( 170 lookup( strings, "Headerdate"), ": ", 171 stddate(gettoday()) 172 ) 173 ) 174 nl() nl() 175 176 call descendants(indi, "1", generation_count, spousefamilies) 177 output_terminate() 178} 179 180 181 182proc descendants (indi, number, generation_count, spousefamilies) { 183 output_startpara() 184 number output_linebreak() 185 call print_person(indi, 1) 186 187 call write_notes(indi) 188 189 set(childnumber, 0) 190 191 families(indi, family, spouse, i) { 192 if(e, marriage(family)) { 193 lookup( strings, "Married") " " stddate(e) 194 } else { 195 lookup( strings, "Relationship") 196 } 197 198 if ( ne( spouse, null)) { 199 " " lookup( strings, "with") " " 200 call print_person(spouse, 1) 201 } else { 202 " " lookup( strings, "with") " " 203 lookup( strings, "unknownspouse") 204 } 205 206 if ( ne(spousefamilies, 0)) { 207 families(spouse, spfamily, spspouse, j) { 208 if (ne(family, spfamily)) { 209 name(spouse) " " 210 lookup( strings, "had") " " 211 d(nchildren(spfamily)) " " 212 lookup( strings, "children") 213 if ( ne( spspouse, null)) { 214 " " lookup( strings, "with") " " 215 call print_person(spspouse, 0) 216 } else { 217 " " lookup( strings, "with") " " 218 lookup( strings, "unknownspouse") 219 } 220 if( eq(spousefamilies, 2)) { 221 output_leftin() 222 children(spfamily, child, k) { 223 "\t" 224 call print_person(child, 0) 225 } 226 output_leftout() 227 } 228 } 229 } 230 } 231 232 call write_notes(spouse) 233 234 output_leftin() 235 children(family, child, j) { 236 "\t" number "." d(add(j, childnumber)) nl() "\t" 237 call print_person(child, 1) 238 } 239 output_leftout() 240 set(childnumber, add(childnumber, j)) 241 } 242 243 output_endpara() 244 245 set(childnumber, 0) 246 247 families(indi, family, spouse, i) { 248 if (ne(1, generation_count)) { 249 if ( gt(generation_count, 1)) { 250 decr(generation_count) 251 } 252 children(family, child, j) { 253 call descendants ( 254 child, 255 strconcat( 256 number, ".", 257 d(add(j, childnumber)) 258 ), 259 generation_count, spousefamilies) 260 } 261 set(childnumber, add(childnumber, j)) 262 } 263 } 264 265} 266 267 268 269proc write_notes(indi) { 270 set(done_header, 0) 271 fornodes(inode(indi), node) { 272 if (eq(0,strcmp("FILE", tag(node)))) { 273 if ( eq(done_header, 0) ) { 274 lookup( strings, "Notesfor") " " 275 name(indi) ":" output_linebreak() 276 incr(done_header) 277 } 278 copyfile(value(node)) 279 } elsif (eq(0,strcmp("NOTE", tag(node)))) { 280 if ( eq(done_header, 0) ) { 281 lookup( strings, "Notesfor") " " 282 name(indi) ":" output_linebreak() 283 incr(done_header) 284 } 285 value(node) 286 fornodes(node, subnode) { 287 if (eq(0,strcmp("CONT", tag(subnode)))) { 288 nl() value(subnode) 289 } 290 } 291 output_linebreak() 292 } 293 } 294} 295 296 297proc print_person (indi, bold) { 298 if(bold) { 299 output_bold( name(indi)) 300 } else { 301 name(indi) 302 } 303 if (e, stddate(birth(indi))) { 304 ", " lookup( strings, "Born") " " e 305 } 306 if(e, stddate(death(indi))) { 307 ", " lookup( strings, "Dead") " " e 308 } 309 "." output_linebreak() 310} 311 312 313func output_header1 (string) { 314 if ( eq( outputtype, 1)) { 315 return(concat( ".(b C", nl(), ".ps 16", nl(), "\\fB", 316 split(string), "\\fP", nl(), 317 ".ps 8", nl(), ".)b", nl())) 318 } 319 if ( eq( outputtype, 2)) { 320 return(concat( "<H1>", string, "</H1>")) 321 } 322 return(string) 323} 324 325func output_header2 (string) { 326 if ( eq( outputtype, 1)) { 327 return(concat( ".(b C", nl(), ".ps 12", nl(), "\\fB", 328 string, "\\fP", nl(), 329 ".ps 8", nl(), ".)b", nl())) 330 } 331 if ( eq( outputtype, 2)) { 332 return(concat( "<H2>", string, "</H2>")) 333 } 334 return(string) 335} 336 337 338func output_init () { 339 if ( eq( outputtype, 1)) { 340 return(concat( ".po 0.8i", nl(), ".ll 6.8i", nl(), 341 ".pl +1.5i", nl(), ".nf", nl(), ".ps 8", nl())) 342 } 343 if ( eq( outputtype, 2)) { 344 return(concat("<HTML><HEAD><TITLE>Descendant chart</TITLE></HEAD><BODY>", nl() )) 345 } 346} 347 348 349func output_terminate () { 350 if ( eq( outputtype, 2)) { 351 return("</BODY></HTML>") 352 } 353} 354 355 356func output_linebreak () { 357 if ( eq( outputtype, 1)) { 358 return(nl()) 359 } 360 if ( eq( outputtype, 2)) { 361 return("<BR>") 362 } 363 return(nl()) 364} 365 366 367func output_startpara () { 368 if ( eq( outputtype, 2)) { 369 return("<P>") 370 } 371} 372 373 374func output_endpara () { 375 if ( eq( outputtype, 2)) { 376 return("</P>") 377 } 378 return(concat( output_linebreak(), output_linebreak())) 379} 380 381func output_bold (string) { 382 if ( eq( outputtype, 1)) { 383 return(concat( "\\fB", string, "\\fP")) 384 } 385 if ( eq( outputtype, 2)) { 386 return(concat( "<B>", string, "</B>")) 387 } 388 return(string) 389} 390 391 392func output_leftin () { 393 if ( eq( outputtype, 2)) { 394 return(concat( "<TABLE WIDTH=100%><TR><TD WIDTH=5%></TD><TD>")) 395 } 396} 397 398 399func output_leftout () { 400 if ( eq( outputtype, 2)) { 401 return(concat( "</TD></TR></TABLE>")) 402 } 403} 404 405 406func split(string) { 407 set(i, 1) 408 set(tmpstr, "") 409 while( ne( i, strlen(string))) { 410 if ( nestr( substring( string, i, i), " ")) { 411 set(tmpstr, concat(tmpstr, substring( string, i, i))) 412 } else { 413 set(tmpstr, concat(tmpstr, "\\0")) 414 } 415 incr(i) 416 } 417 return (tmpstr) 418} 419 420 421/* Sample output: 422 423 424Successors of N.N. Helgesdtr. �SE with 2 generations descendants 425 426Date: 14 Jun 1995 427 4281 429N.N. Helgesdtr. �SE. 430Relationship with Tjeran Hallvardson (Halldors.) VASSHUS, Born 1610. 431Notes for Tjeran Hallvardson (Halldors.) VASSHUS: 432Er nevnt som leilending i 1635 sammen med Helge �se som sannsynligvis var 433hans svigerfar. 434Tjeran og broren Rasmus stevnet stefaren Laurits Asserson for odelsgods i 435Kluge, Gjesdal som deres mor eide. 436 1.1 437 Lars Tjeranson �SE, Born 1643, Dead 9 Jun 1702. 438 1.2 439 Marite Tjerandsdtr. �SE, Dead 1691. 440 1.3 441 Hallvard TJERANSON, Born 1651. 442 1.4 443 Helge TJERANSON, Born 1654. 444 445 4461.1 447Lars Tjeranson �SE, Born 1643, Dead 9 Jun 1702. 448Notes for Lars Tjeranson �SE: 449Gift I med Kirsti Olsdtr. Malmeim (f.1665 d.12.04.1695). 450II med Johanna Gunnarsdtr. Sveinsvoll (d.1741). 451Lars hadde v�rt soldat i 10 �r. 2 barn kjent. 452 453 4541.2 455Marite Tjerandsdtr. �SE, Dead 1691. 456Relationship with Ola Olson KJOSAVIK, Born 1623, Dead 9 1702. 457Ola Olson KJOSAVIK had 7 children with KariI Pedersdtr., Born 16 , Dead 1674. 458Ola Olson KJOSAVIK had 1 children with KariII Torkellsdtr. ALSNES, Born 1661, Dead 30 Mar 1705. 459Notes for Ola Olson KJOSAVIK: 4607 barn av f�rste ekteskap, 3 av andre og 1 av tredje ekteskap. 461 1.2.1 462 Berit Olsdtr. KJOSAVIK, Born 1674, Dead 1746. 463 1.2.2 464 Kristoffer Olson KJOSAVIK, Born 1677. 465 1.2.3 466 Ola O. KJOSAVIK, Born 1681, Dead 23 1695. 467 468. 469. 470. 471 472*/ 473