Ancestral line from " upper(name(indi(k))) "\n"
}
proc nroffPara () {
".P\n"
}
proc sgmlPara () {
"\n"
}
proc nroffLeftSquareBracket () {
"["
}
proc sgmlLeftSquareBracket () {
"["
}
proc nroffRightSquareBracket () {
"]"
}
proc sgmlRightSquareBracket () {
"]"
}
proc nroffStartList () {
"\n"
}
proc sgmlStartList () {
"\n"
}
proc nroffEndList () {
"\n"
}
proc sgmlEndList () {
"\n"
}
proc nroffChildItem () {
" "
}
proc sgmlChildItem () {
"- \n"
}
/*
* WriteChildren - This routine writes out the children for a person in an
* ancestral line.
*/
proc WriteChildren (e)
{
set(p, indi(getel(e, 1)))
set(cl, getel(e, 6)) /* list of child keys also in this line */
families (p, f, s, n) {
if (s) { set(u, save(name(s))) }
else { set(u, "(_____)") }
if (lookup(FamT, key(f))) {
call EmitPara()
"Children of " name(p) " and " u
" listed under " u ".\n"
} elsif (gt(nchildren(f), 0)) {
call EmitPara()
"Children of " name(p) " and " u ":\n"
call EmitStartList()
children(f, c, m) {
if (inlist(cl, key(c))) {
set(ce, lookup(AncT, key(c)))
call EmitChildItem()
d(getel(ce, 2)) " "
roman(m) "\n"
call shortvitals(c)
} else {
call EmitChildItem()
roman(m) "\n"
call middlevitals(c)
}
}
insert(FamT, savekey(key(f)), 1)
call EmitEndList()
}
}
}
proc shortvitals (i)
{
name(i)
set(b, birth(i)) set(d, death(i))
if (and(b, short(b))) { ", b. " short(b) }
if (and(d, short(d))) { ", d. " short(d) }
".\n"
call EmitPara()
}
proc middlevitals (i)
{
name(i) ".\n"
set(e, birth(i))
if(and(e,long(e))) {
call EmitPara()
"Born " long(e) ".\n" }
if (eq(1, nspouses(i))) {
spouses(i, s, f, n) {
call EmitPara()
"Married"
call spousevitals(s, f)
}
} else {
spouses(i, s, f, n) {
call EmitPara()
"Married " ord(n) ","
call spousevitals(s, f)
}
}
set(e, death(i))
if(and(e, long(e))) {
call EmitPara()
"Died " long(e) ".\n" }
set(p, 0)
}
/*
* WriteLinePerson - This routine generates the report output for one
* person in one of the ancestral lines. This version of the routine
* generates output in nroff format. It prints boiler plate vitals
* information about the person followed by all notes in the person's
* record in the database. This routine does not print the person's
* children (see routine >>>>> for this).
*/
proc WriteLinePerson (e)
{
set(p, indi(getel(e, 1)))
call EmitPara()
d(getel(e, 2)) " "
name(p)
if (ORel) {
call EmitLeftSquareBracket()
set(c, "")
forlist (getel(e, 5), r, n) {
c call ShowRel(r) set(c, ", ")
}
call EmitRightSquareBracket()
}
".\n"
call EmitPara()
set(o, birth(p))
if(and(o, long(o))) { "Born " long(o) ".\n" }
if (eq(1, nspouses(p))) {
spouses(p, s, f, n) {
"Married"
call spousevitals(s, f)
}
} else {
spouses(p, s, f, n) {
"Married " ord(n) ","
call spousevitals(s, f)
}
}
set(o, death(p))
if(and(o, long(o))) { "Died " long(o) ".\n" }
set(b, 0)
fornotes(root(p), n) {
if (not(b)) {
call EmitPara()
set(b, 1) }
n "\n"
}
}
proc spousevitals (s, f)
{
set(e, marriage(f))
if (and(e, long(e))) { "\n" long(e) "," }
"\n" name(s)
set(e, birth(s))
if (and(e, long(e))) { ",\nborn " long(e) }
set(e, death(s))
if (and(e, long(e))) { ",\ndied " long(e) }
set(d, LineParent(s))
set(m, OthrParent(s))
if (or(d, m)) {
",\n"
if (male(s)) { "son of " }
elsif (female(s)) { "daughter of " }
else { "child of " }
}
if (d) { name(d) }
if (and(d, m)) { "\nand " }
if (m) { name(m) }
".\n"
}
/*
* ShowBOLLists - This debug routine shows the bottom of line persons as
* recorded in the BOLK, BOLG, and BOLR lists
*/
proc ShowBOLLists ()
{
forlist(BOLK, k, n) {
set(g, getel(BOLG, n)) set(r, getel(BOLR, n))
name(indi(k)) " " d(g) " "
d(r) " (" call ShowRel(r) ")\n"
}
}
proc ShowCurLine ()
{
set(k, pop(CurK))
set(p, indi(k))
while (p) {
set(g, pop(CurG)) set(r, pop(CurR))
name(p) " (" d(g) "," d(r) ") "
set(k, pop(CurK)) set(p, indi(k))
}
"\n"
}
/* ShowAncTable -- Debug routine which shows contents of AncT. */
proc ShowAncTable ()
{
forlist(AncL, k, n) {
set(e, lookup(AncT, k))
set(p, indi(k))
set(i, getel(e, 2))
set(g, getel(e, 4))
set(r, getel(e, 5))
set(d, getel(e, 6))
k " " name(p) " " d(i) " "
forlist (g, j, l) { d(getel(g, l)) " " }
forlist (r, j, l) { call ShowRel(getel(r, l)) " " }
forlist (d, c, l) { name(indi(c)) " " }
"\n"
}
}
proc ShowRel (r)
{
if (eq(r, 1)) { "s" }
if (gt(r, 1)) {
list(RelStack)
push(RelStack, neg(1))
while (gt(r, 1)) {
set(m, mod(r, 2))
set(r, div(r, 2))
push(RelStack, m)
}
set(r, pop(RelStack))
while (ne(r, neg(1))) {
if (r) { "m" }
else { "f" }
set(r, pop(RelStack))
}
}
}
/* inlist -- See if a string is in a list of strings */
func inlist (l, s)
{
forlist(l, e, n) {
if (eqstr(e, s)) { return(1) }
}
return(0)
}
func savekey (k)
{
if (e, lookup(KeyT, k)) { return(e) }
set(k, save(k))
insert(KeyT, k, k)
return(k)
}