2
* @progname paf-import.ll
4
* @author Kurt Baudendistel (baud@research.att.com)
9
* Convert paf gedcom to lifelines-standard gedcom,
10
* transforming name formats and notes.
12
* First, some silly formating:
14
* 1. _'s in NAMEs are converted to spaces.
15
* 2. Leading commas are stripped from PLACes
16
* 3. Recognizable posttitles are moved from TITL entries to NAME
19
* Then, the meat of the problem
21
* 4. Bang-tagged NOTEs of the form
23
* 1 NOTE !BIRTH-CHRISTENING: ...
26
* are converted to SOURs in the appropriate event, and the
27
* original NOTE is deleted. The following NOTEs are recognized and
28
* translated into the corresponding event (an event is created
29
* if it does not exist):
40
* MARRIAGE -> MARR (in first associated family)
41
* MARRIAGE(N) -> MARR (in numbered associated family)
42
* MARRIAGES -> MARR (in all associated families)
43
* DIVORCE -> DIV (in first associated family)
44
* DIVORCE(N) -> DIV (in numbered associated family)
45
* DIVORCES -> DIV (in all associated families)
46
* DIVORCEFINAL -> DIVF (in first associated family)
47
* DIVORCEFINAL(N) -> DIVF (in numbered associated family)
48
* DIVORCEFINALS -> DIVF (in all associated families)
49
* ANNULMENT -> ANUL (in first associated family)
50
* ANNULMENT(N) -> ANUL (in numbered associated family)
51
* ANNULMENTS -> ANUL (in all associated families)
53
* The NOTE is not deleted if any of the components are not
54
* recognized. Plain bang-tagged NOTEs are converted to TEXT.
56
* Multiple NOTEs produce multiple SOURs, just as you would expect.
58
* 5. Non-bang-tagged NOTEs of the form
63
* are converted to NOTEs in the appropriate event for those
64
* events listed above, and the original NOTE is deleted. Note
65
* multiple NOTE targets (as in BIRTH-CHRISTENING) are not allowed
66
* for non-bang-tagged NOTEs, and that containing nodes (like
67
* PLAC) are not created if they do not exist -- the NOTE is simply
70
* For the following NOTEs, a record is created of the
71
* indicated type (death here can be replaced by any event):
73
* DEATHSITE -> DEAT - PLAC - SITE
74
* DEATHAGE -> DEAT - AGE
75
* DEATHCAUSE -> DEAT - CAUS
76
* CEMETERY -> (same as BURIALSITE)
77
* EDITOR -> SOUR (at level 1)
78
* RESEARCHER -> SOUR (at level 1)
81
* Of course, the original note is deleted.
83
* From: paf baud@research.att.com
85
* 12 NOV 1994 (2.3.6) baud@research.att.com
88
global (tTagTranslation)
89
global (tTitleTransformation)
90
global (sourceListTable)
91
global (siteListTable)
93
global (causeListTable)
94
global (noteListTable)
97
global (tNotesToDelete)
104
"2 NAME PAF-IMPORT REPORT\n"
106
"1 DATE " date (gettoday ()) "\n"
109
table (tTagTranslation)
110
insert (tTagTranslation, "NAME", "NAME")
111
insert (tTagTranslation, "BIRTH", "BIRT")
112
insert (tTagTranslation, "PARENTS", "BIRT")
113
insert (tTagTranslation, "FATHER", "BIRT")
114
insert (tTagTranslation, "MOTHER", "BIRT")
115
insert (tTagTranslation, "ADOPTION", "ADOP")
116
insert (tTagTranslation, "CHRISTENING", "CHR")
117
insert (tTagTranslation, "DEATH", "DEAT")
118
insert (tTagTranslation, "BURIAL", "BURI")
119
insert (tTagTranslation, "MARRIAGE", "MARR")
120
insert (tTagTranslation, "DIVORCE", "DIV")
121
insert (tTagTranslation, "DIVORCEFINAL", "DIVF")
122
insert (tTagTranslation, "ANNULMENT", "ANUL")
123
insert (tTagTranslation, "EDITOR", "SOUR")
124
insert (tTagTranslation, "RESEARCHER", "SOUR")
125
insert (tTagTranslation, "OCCUPATION", "OCCU")
127
table (tTitleTransformation)
128
insert (tTitleTransformation, "Jr", "")
129
insert (tTitleTransformation, "Sr", "")
130
insert (tTitleTransformation, "I", "")
131
insert (tTitleTransformation, "II", "")
132
insert (tTitleTransformation, "III", "")
133
insert (tTitleTransformation, "IV", "")
134
insert (tTitleTransformation, "V", "")
135
insert (tTitleTransformation, "MD", "Dr")
136
insert (tTitleTransformation, "DDS", "Dr")
137
insert (tTitleTransformation, "PhD", "Dr")
138
insert (tTitleTransformation, "SJ", "Father")
139
insert (tTitleTransformation, "SM", "Brother")
141
table (sourceListTable)
142
table (siteListTable)
144
table (causeListTable)
145
table (noteListTable)
148
insert (tIndiEvents, "NAME", 1)
149
insert (tIndiEvents, "BIRT", 1)
150
insert (tIndiEvents, "ADOP", 1)
151
insert (tIndiEvents, "CHR", 1)
152
insert (tIndiEvents, "DEAT", 1)
153
insert (tIndiEvents, "BURI", 1)
154
insert (tIndiEvents, "SOUR", 1)
155
insert (tIndiEvents, "OCCU", 1)
158
insert (tFamEvents, "MARR", 1)
159
insert (tFamEvents, "DIV", 1)
160
insert (tFamEvents, "DIVF", 1)
161
insert (tFamEvents, "ANUL", 1)
163
table (tNotesToDelete)
165
print ("Scanning for sources and event notes (x10) ...\n")
166
forindi (indi, num) {
167
if (eq (mod(num,10),0)) {
170
call unpafSources (indi)
171
call unpafOthers (indi, "SITE", siteListTable)
172
call unpafOthers (indi, "AGE", ageListTable)
173
call unpafOthers (indi, "CAUSE", causeListTable)
174
call unpafOthers (indi, "", noteListTable)
177
print ("\n\nProcessing nodes (x10) ...\n")
178
forindi (indi, num) {
179
if (eq (mod(num,10),0)) {
182
call unpafNode (key (indi), inode (indi))
186
if (eq (mod(num,10),0)) {
189
call unpafNode (key (fam), fnode (fam))
195
proc unpafSources (indi)
197
fornodes (inode (indi), node) {
198
if (not (strcmp (tag (node), "NOTE"))) {
199
set (note, value (node))
200
if (eq (index (note, "!", 1), 1)) {
201
if (colon, index (note, ":", 1)) {
202
set (nTag, save (concat (substring (note, 2, sub (colon, 1)), "-")))
204
while (strcmp (nTag, "")) {
205
set (mark, index (nTag, "-", 1))
206
set (bTag, save (substring (nTag, 1, sub (mark, 1))))
207
set (nTag, save (substring (nTag, add (mark, 1), strlen (nTag))))
208
set (openLoc, add (index (bTag, "("/*)*/, 1), 1))
209
set (closLoc, sub (index (bTag, /*(*/")", 1), 1))
210
if (le (openLoc, closLoc)) {
211
if (bNum, atoi (substring (bTag, openLoc, closLoc))) {
212
set (bTag, save (trim (bTag, sub (openLoc, 2))))
219
if (evt, lookup (tTagTranslation, bTag)) {
221
if (lookup (tIndiEvents, evt)) {
223
set (sourceKey, save (concat (key (indi), evt)))
225
} elsif (lookup (tFamEvents, evt)) {
227
families (indi, fvar, svar, num) {
228
if (eq (bNum, num)) {
229
set (sourceKey, save (concat (key (fvar), evt)))
233
if (not (foundFlag)) {
237
if (strcmp (sourceKey, "")) {
238
call insertListTable (sourceListTable, sourceKey, node)
245
insert (tNotesToDelete, save (value (node)), 1)
253
proc unpafOthers (indi, kind, otherListTable)
255
set (tail, save (concat (kind, ":")))
256
fornodes (inode (indi), node) {
257
if (not (strcmp (tag (node), "NOTE"))) {
258
set (note, value (node))
259
if (eq (index (note, "CEMETERY:", 1), 1)) {
261
save (concat ("BURIALSITE", substring (note, 9, strlen (note)))))
263
set (tailIndex, index (note, tail, 1))
264
set (spaceIndex, index (note, " ", 1))
265
if (or (lt (tailIndex, spaceIndex),
266
and (eq (spaceIndex, 0),
267
gt (tailIndex, 0)))) {
268
set (bEnd, sub (tailIndex, 1))
269
set (bTag, save (trim (note, bEnd)))
270
set (bNum, atoi (substring (bTag, bEnd, bEnd)))
273
set (bTag, save (trim (bTag, bEnd)))
276
if (evt, lookup (tTagTranslation, bTag)) {
278
if (lookup (tIndiEvents, evt)) {
280
set (otherKey, save (concat (key (indi), evt)))
282
} elsif (lookup (tFamEvents, evt)) {
283
families (indi, fvar, svar, num) {
284
if (eq (bNum, num)) {
285
set (otherKey, save (concat (key (fvar), evt)))
289
if (strcmp (otherKey, "")) {
290
call insertListTable (otherListTable, otherKey, node)
291
insert (tNotesToDelete, save (value (node)), 1)
299
proc insertListTable (listTable, tableKey, node) {
301
set (note, value (node))
303
save (substring (note, add (index (note, ":", 1), 1), strlen (note))))
304
if (not (strcmp (trim (first, 1), " "))) {
305
set (first, save (substring (first, 2, strlen (first))))
307
if (strlen (first)) {
308
enqueue (evtList, first)
311
if (not (strcmp ("CONT", tag (n)))) {
312
enqueue (evtList, save (value (n)))
315
set (entryList, lookup (listTable, tableKey))
316
if (not (entryList)) { list (entryList) }
317
enqueue (entryList, evtList)
318
insert (listTable, tableKey, entryList)
321
proc unpafNode (rootKey, root)
326
traverse (root, node, level) {
327
set (sawBIRT, or (sawBIRT, not (strcmp (tag (node), "BIRT"))))
329
set (deletingFlag, 0)
330
set (listTableKey, save (concat (rootKey, tag (node))))
331
set (sourceList, lookup (sourceListTable, listTableKey))
332
if (unbangedSourceList, lookup (noteListTable, listTableKey)) {
333
while (evt, dequeue (unbangedSourceList)) {
334
enqueue (sourceList, evt)
337
} elsif (eq (level, 1)) {
339
while (evt, dequeue (sourceList)) {
340
call reTagNote (add (level, 1), "SOUR", evt)
345
while (evt, dequeue (noteList)) {
346
call reTagNote (add (level, 1), "TEXT", evt)
350
set (listTableKey, save (concat (rootKey, tag (node))))
351
set (sourceList, lookup (sourceListTable, listTableKey))
352
set (noteList, lookup (noteListTable, listTableKey))
353
set (deletingFlag, and (not (strcmp (tag (node), "NOTE")),
354
lookup (tNotesToDelete, value (node))))
356
if (not (deletingFlag)) {
358
if (xref (node)) { xref (node) " " }
359
set (text, value (node))
360
if (not (strcmp (tag (node), "NAME"))) {
361
while (ind, index (text, "_", 1)) {
363
save (concat (concat (substring (text, 1, sub (ind,1)), " "),
364
substring (text, add (ind, 1), strlen (text)))))
367
} elsif (not (strcmp (tag (node), "TITL"))) {
368
if (titl, lookup (tTitleTransformation, text)) {
371
d (level) " TITL " titl "\n"
376
} elsif (not (strcmp (tag (node), "PLAC"))) {
377
while (not (strcmp (trim (text, 1), ","))) {
378
set (text, save (substring (text, 2, strlen (text))))
381
if (siteList, lookup (siteListTable, listTableKey)) {
382
while (evt, dequeue (siteList)) {
383
call reTagNote (add (level, 1), "SITE", evt)
386
} elsif (not (strcmp (tag (node), "NOTE"))) {
387
if (not (strcmp (trim (text, 1), "!"))) {
394
tag (node) " " text "\n"
395
if (ageList, lookup (ageListTable, listTableKey)) {
396
while (evt, dequeue (ageList)) {
397
call reTagNote (add (level, 1), "AGE", evt)
400
if (causeList, lookup (causeListTable, listTableKey)) {
401
while (evt, dequeue (causeList)) {
402
call reTagNote (add (level, 1), "CAUS", evt)
408
set (listTableKey, save (concat (rootKey, BIRT)))
409
set (sourceList, lookup (sourceListTable, listTableKey))
410
set (noteList, lookup (noteListTable, listTableKey))
411
if (and (or (sourceList, noteList), not (sawBIRT))) {
414
while (evt, dequeue (sourceList)) {
415
call reTagNote (2, "SOUR", evt)
419
while (evt, dequeue (noteList)) {
420
call reTagNote (2, "TEXT", evt)
426
proc reTagNote (relevel, retag, revalueList) {
427
set (contLevel, add (relevel, 1))
428
forlist (revalueList, revalue, rv) {
429
d (relevel) " " retag " " revalue "\n"
430
set (relevel, contLevel)