gedcom 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +4 -0
- data/Manifest.txt +74 -0
- data/README.txt +129 -0
- data/Rakefile +13 -0
- data/lib/gedcom.rb +105 -0
- data/lib/gedcom/address_record.rb +77 -0
- data/lib/gedcom/adoption_record.rb +57 -0
- data/lib/gedcom/association_record.rb +79 -0
- data/lib/gedcom/cause_record.rb +45 -0
- data/lib/gedcom/change_date_record.rb +39 -0
- data/lib/gedcom/character_set_record.rb +41 -0
- data/lib/gedcom/citation_data_record.rb +49 -0
- data/lib/gedcom/citation_event_type_record.rb +42 -0
- data/lib/gedcom/corporate_record.rb +36 -0
- data/lib/gedcom/date_record.rb +206 -0
- data/lib/gedcom/encoded_line_record.rb +34 -0
- data/lib/gedcom/event_age_record.rb +36 -0
- data/lib/gedcom/event_record.rb +258 -0
- data/lib/gedcom/events_list_record.rb +61 -0
- data/lib/gedcom/families_individuals.rb +79 -0
- data/lib/gedcom/family_record.rb +89 -0
- data/lib/gedcom/gedcom_all.rb +41 -0
- data/lib/gedcom/gedcom_base.rb +337 -0
- data/lib/gedcom/gedcom_record.rb +44 -0
- data/lib/gedcom/header_data_record.rb +49 -0
- data/lib/gedcom/header_record.rb +75 -0
- data/lib/gedcom/header_source_record.rb +42 -0
- data/lib/gedcom/individual_attribute_record.rb +86 -0
- data/lib/gedcom/individual_record.rb +128 -0
- data/lib/gedcom/multimedia_citation_record.rb +55 -0
- data/lib/gedcom/multimedia_record.rb +72 -0
- data/lib/gedcom/name_record.rb +58 -0
- data/lib/gedcom/note_citation_record.rb +37 -0
- data/lib/gedcom/note_record.rb +61 -0
- data/lib/gedcom/place_record.rb +46 -0
- data/lib/gedcom/refn_record.rb +32 -0
- data/lib/gedcom/repository_caln.rb +33 -0
- data/lib/gedcom/repository_citation_record.rb +43 -0
- data/lib/gedcom/repository_record.rb +41 -0
- data/lib/gedcom/source_citation_record.rb +74 -0
- data/lib/gedcom/source_record.rb +84 -0
- data/lib/gedcom/source_scope_record.rb +35 -0
- data/lib/gedcom/submission_record.rb +53 -0
- data/lib/gedcom/submitter_record.rb +53 -0
- data/lib/gedcom/text_record.rb +31 -0
- data/lib/gedcom/trailer_record.rb +22 -0
- data/lib/gedcom/transmission.rb +103 -0
- data/lib/gedcom/transmission_base.rb +267 -0
- data/lib/parser/class_tracker.rb +33 -0
- data/lib/parser/ged_line.rb +99 -0
- data/lib/parser/gedcom_parser.rb +798 -0
- data/lib/parser/instruction.rb +14 -0
- data/lib/parser/parse_state.rb +49 -0
- data/test/test_gedcom.rb +7 -0
- data/test_data/Document.RTF +1 -0
- data/test_data/Document.tex +1 -0
- data/test_data/ImgFile.BMP +0 -0
- data/test_data/ImgFile.GIF +0 -0
- data/test_data/ImgFile.JPG +0 -0
- data/test_data/ImgFile.MAC +0 -0
- data/test_data/ImgFile.PCX +0 -0
- data/test_data/ImgFile.PIC +0 -0
- data/test_data/ImgFile.PNG +0 -0
- data/test_data/ImgFile.PSD +0 -0
- data/test_data/ImgFile.TGA +0 -0
- data/test_data/ImgFile.TIF +0 -0
- data/test_data/README.txt +1 -16
- data/test_data/TGC551.ged +1 -0
- data/test_data/TGC551LF.ged +2162 -0
- data/test_data/TGC55C.ged +1 -0
- data/test_data/TGC55CLF.ged +2202 -0
- data/test_data/force.wav +0 -0
- data/test_data/suntun.mov +0 -0
- data/test_data/top.mpg +0 -0
- metadata +140 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'gedcom_base.rb'
|
2
|
+
|
3
|
+
#Family_record is the internal representation of a level 0 GEDCOM FAM record.
|
4
|
+
#
|
5
|
+
#=FAM_RECORD:=
|
6
|
+
# 0 @<XREF:FAM>@ FAM {0:M}
|
7
|
+
# +1 <<FAMILY_EVENT_STRUCTURE>> {0:M} p.28
|
8
|
+
# +2 HUSB {0:1}
|
9
|
+
# +3 AGE <AGE_AT_EVENT> {1:1} p.35
|
10
|
+
# +2 WIFE {0:1}
|
11
|
+
# +3 AGE <AGE_AT_EVENT> {1:1}
|
12
|
+
# +1 HUSB @<XREF:INDI>@ {0:1} p.52
|
13
|
+
# +1 WIFE @<XREF:INDI>@ {0:1} p.52
|
14
|
+
# +1 CHIL @<XREF:INDI>@ {0:M} p.52
|
15
|
+
# +1 NCHI <COUNT_OF_CHILDREN> {0:1} p.37
|
16
|
+
# +1 SUBM @<XREF:SUBM>@ {0:M} p.52
|
17
|
+
# +1 <<LDS_SPOUSE_SEALING>> {0:M} p.30
|
18
|
+
# +1 <<SOURCE_CITATION>> {0:M} p.32
|
19
|
+
# +1 <<MULTIMEDIA_LINK>> {0:M} p.30,23
|
20
|
+
# +1 <<NOTE_STRUCTURE>> {0:M} p.31
|
21
|
+
# +1 REFN <USER_REFERENCE_NUMBER> {0:M} p.51
|
22
|
+
# +2 TYPE <USER_REFERENCE_TYPE> {0:1} p.51
|
23
|
+
# +1 RIN <AUTOMATED_RECORD_ID> {0:1} p.36
|
24
|
+
# +1 <<CHANGE_DATE>> {0:1} p.27
|
25
|
+
#
|
26
|
+
# The FAMily record is used to record marriages, common law marriages, and family unions caused by
|
27
|
+
# two people becoming the parents of a child (i.e they may not be married). There can be no more
|
28
|
+
# than one HUSB/father and one WIFE/mother listed in each FAM_RECORD. We are recording parentage,
|
29
|
+
# rather than marriages per se. If, for example, a man participated in more than one
|
30
|
+
# family union (or with more than 1 wife) then he would appear in more than one FAM_RECORD. The
|
31
|
+
# family record structure assumes that the HUSB/father is male and WIFE/mother is female. Again,
|
32
|
+
# as we are recording parentage, and we can't yet clone or reproduce from two males. or from two females.
|
33
|
+
#
|
34
|
+
# The preferred order of the CHILdren pointers within a FAMily structure is chronological by birth.
|
35
|
+
#
|
36
|
+
#The attributes are all arrays for the level +1 tags/records.
|
37
|
+
#* Those ending in _ref are GEDCOM XREF index keys
|
38
|
+
#* Those ending in _record are array of classes of that type.
|
39
|
+
#* The remainder are arrays of attributes that could be present in this record.
|
40
|
+
class Family_record < GEDCOMBase
|
41
|
+
attr_accessor :restriction #not standard at the event level, but we might want this in DB.
|
42
|
+
attr_accessor :family_ref, :event_record, :husband_ref, :wife_ref, :child_ref, :number_children, :submitter_ref
|
43
|
+
attr_accessor :source_citation_record, :multimedia_citation_record
|
44
|
+
attr_accessor :note_citation_record, :refn_record, :automated_record_id, :change_date_record
|
45
|
+
|
46
|
+
ClassTracker << :Family_record
|
47
|
+
|
48
|
+
#new sets up the state engine arrays @this_level and @sub_level, which drive the to_gedcom method generating GEDCOM output.
|
49
|
+
def initialize(*a)
|
50
|
+
super(*a)
|
51
|
+
@this_level = [ [:xref, "FAM", :family_ref] ]
|
52
|
+
@sub_level = [ #level + 1
|
53
|
+
[:xref, "HUSB", :husband_ref],
|
54
|
+
[:xref, "WIFE", :wife_ref],
|
55
|
+
[:xref, "CHIL", :child_ref],
|
56
|
+
[:print, "NCHI", :number_children],
|
57
|
+
[:walk, nil, :event_record],
|
58
|
+
[:xref, "SUBM", :submitter_ref],
|
59
|
+
[:walk, nil, :multimedia_citation_record],
|
60
|
+
[:walk, nil, :source_citation_record],
|
61
|
+
[:walk, nil, :note_citation_record],
|
62
|
+
[:walk, nil, :refn_record],
|
63
|
+
[:print, "RIN", :automated_record_id],
|
64
|
+
[:walk, nil, :change_date_record],
|
65
|
+
]
|
66
|
+
end
|
67
|
+
|
68
|
+
def id
|
69
|
+
#temporary
|
70
|
+
@family_ref
|
71
|
+
end
|
72
|
+
|
73
|
+
def husband
|
74
|
+
if @husband_ref != nil
|
75
|
+
find(@husband_ref[0], @husband_ref[1])
|
76
|
+
else
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def wife
|
82
|
+
if @wife_ref != nil
|
83
|
+
find(@wife_ref[0], @wife_ref[1])
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'address_record.rb'
|
2
|
+
require 'adoption_record.rb'
|
3
|
+
require 'cause_record.rb'
|
4
|
+
require 'change_date_record.rb'
|
5
|
+
require 'character_set_record.rb'
|
6
|
+
require 'citation_data_record.rb'
|
7
|
+
require 'citation_event_type_record.rb'
|
8
|
+
require 'corporate_record.rb'
|
9
|
+
require 'date_record.rb'
|
10
|
+
require 'encoded_line_record.rb'
|
11
|
+
require 'event_age_record.rb'
|
12
|
+
require 'event_record.rb'
|
13
|
+
require 'events_list_record.rb'
|
14
|
+
require 'families_individuals.rb'
|
15
|
+
require 'family_record.rb'
|
16
|
+
require 'gedcom_base.rb'
|
17
|
+
require 'gedcom_record.rb'
|
18
|
+
require 'header_data_record.rb'
|
19
|
+
require 'header_record.rb'
|
20
|
+
require 'header_source_record.rb'
|
21
|
+
require 'individual_attribute_record.rb'
|
22
|
+
require 'individual_record.rb'
|
23
|
+
require 'association_record.rb'
|
24
|
+
require 'multimedia_citation_record.rb'
|
25
|
+
require 'multimedia_record.rb'
|
26
|
+
require 'name_record.rb'
|
27
|
+
require 'note_citation_record.rb'
|
28
|
+
require 'note_record.rb'
|
29
|
+
require 'place_record.rb'
|
30
|
+
require 'refn_record.rb'
|
31
|
+
require 'repository_caln.rb'
|
32
|
+
require 'repository_citation_record.rb'
|
33
|
+
require 'repository_record.rb'
|
34
|
+
require 'source_citation_record.rb'
|
35
|
+
require 'source_record.rb'
|
36
|
+
require 'source_scope_record.rb'
|
37
|
+
require 'submission_record.rb'
|
38
|
+
require 'submitter_record.rb'
|
39
|
+
require 'text_record.rb'
|
40
|
+
require 'trailer_record.rb'
|
41
|
+
require 'transmission_base.rb'
|
@@ -0,0 +1,337 @@
|
|
1
|
+
require "class_tracker.rb"
|
2
|
+
require "instruction.rb"
|
3
|
+
|
4
|
+
#base routines shared by all gedcom objects.
|
5
|
+
class GEDCOMBase
|
6
|
+
attr_accessor :class_stack, :indexes
|
7
|
+
@@tabs = false #If true, indent gedcom lines on output a tab per level. Normally wouldn't have tabs in a transmission file.
|
8
|
+
|
9
|
+
#Create a new GEDCOMBase or most likely a subclass of GEDCOMBase.
|
10
|
+
#* transmission is the current transmission this object came from.
|
11
|
+
# This is useful in searchs of the transmission, starting from a reference in a record in that transmission.
|
12
|
+
#* changed indicates that we have altered the data in the record
|
13
|
+
# The default is true, as the normal instantiation is creating a new record.
|
14
|
+
# to_db uses this to determine if the record needs to be saved to the DB.
|
15
|
+
#* created indicates that this is a new record, rather than one we may have loaded from a DB.
|
16
|
+
def initialize(transmission = nil, changed=true,created=true)
|
17
|
+
@changed = changed
|
18
|
+
@created = created
|
19
|
+
@this_level = []
|
20
|
+
@sub_level = []
|
21
|
+
@transmission = transmission
|
22
|
+
end
|
23
|
+
|
24
|
+
#sets @@tabs to true.
|
25
|
+
#This indents gedcom lines on output a tab per level.
|
26
|
+
#This is useful if pretty printing, but not normal in a gedcom file
|
27
|
+
#as most GEDCOM file parsers don't like leading tabs on lines of a transmission file.
|
28
|
+
#I use this only for debugging.
|
29
|
+
def self.tabs
|
30
|
+
@@tabs = true
|
31
|
+
end
|
32
|
+
|
33
|
+
#sets @@tabs to false.
|
34
|
+
#This is the default as a lot of GEDCOM parsers don't like leading white space on lines.
|
35
|
+
def self.no_tabs
|
36
|
+
@@tabs = false #The default
|
37
|
+
end
|
38
|
+
|
39
|
+
#Marks this object as having been altered so we know to synchronise it with the DB.
|
40
|
+
def changed
|
41
|
+
@changed = true
|
42
|
+
end
|
43
|
+
|
44
|
+
#Tests for this object having been altered, so we know to synchronise it with the DB.
|
45
|
+
def changed?
|
46
|
+
@changed
|
47
|
+
end
|
48
|
+
|
49
|
+
#Tests to see if this is a new object, not one we have loaded from elsewhere (say a DB)
|
50
|
+
def created?
|
51
|
+
@created
|
52
|
+
end
|
53
|
+
|
54
|
+
#create a string from the objects instance variables, one per line, in the form "variable = value\n" ... .
|
55
|
+
#For an ordered list, see to_s_ordered
|
56
|
+
def to_s
|
57
|
+
s = ''
|
58
|
+
self.instance_variables.each do |v| #look at each of the instance variables
|
59
|
+
if self.class.method_defined?(v_sym = v[1..-1].to_sym) #see if there is a method defined for this symbol (strip the :)
|
60
|
+
s += "#{v} = " + pv_byname(v_sym) + "\n" #print it
|
61
|
+
end
|
62
|
+
end
|
63
|
+
s
|
64
|
+
end
|
65
|
+
|
66
|
+
#Need to flesh this out. Right now it pretends to work and marks records as saved.
|
67
|
+
def to_db(level = 0, this_level=[], sub_levels=[])
|
68
|
+
@changed = false
|
69
|
+
@created = false
|
70
|
+
end
|
71
|
+
|
72
|
+
#This is the default method, used by all classes inheriting from GEDCOMBase, to recursively generate GEDCOM lines from that Object downward.
|
73
|
+
#All subclasses of GEDCOMBase are expected to define @this_level and @sub_level arrays, which are instructions to to_s_r on how to generate
|
74
|
+
#GEDCOM lines from the attributes of the object.
|
75
|
+
def to_gedcom(level = 0)
|
76
|
+
to_s_r( level, @this_level, @sub_level )
|
77
|
+
end
|
78
|
+
|
79
|
+
#This is the default method, used by all classes inheriting from GEDCOMBase, to recursively save the object and its sub-records to a DB.
|
80
|
+
#All subclasses of GEDCOMBase are expected to define @this_level and @sub_level arrays, which are instructions to to_db on how to generate
|
81
|
+
#GEDCOM lines from the attributes of the object.
|
82
|
+
def save
|
83
|
+
to_db( level, @this_level, @sub_level)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
#Somewhat cryptic. This takes the symbol (variable name) and returns the object associatied with it.
|
89
|
+
def pv_byname(v_sym, indent = 0)
|
90
|
+
a = self.send( v_sym )
|
91
|
+
pv(a)
|
92
|
+
end
|
93
|
+
|
94
|
+
#return a string of ',' separated values stored in the object in the variable v.
|
95
|
+
def pv(v)
|
96
|
+
s = ''
|
97
|
+
if v == nil #nil object
|
98
|
+
s += 'nil'
|
99
|
+
elsif v.class == Array #object is an Array, so enumerate each to get each value (with recursive call).
|
100
|
+
s += "[\n"
|
101
|
+
s += v.inject('') { |x,y| x + pv(y) + ',' }
|
102
|
+
s[-1,1] = "\n"
|
103
|
+
s += "]"
|
104
|
+
s
|
105
|
+
else #object is singular, so return its to_s value if it has one.
|
106
|
+
if x = v.to_s
|
107
|
+
s += x
|
108
|
+
else
|
109
|
+
s += 'nil'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
#Return and empty string unless @@tabs is true.
|
115
|
+
#Returns a string of tabs (actually of pairs of spaces), one pair per GEDCOM level.
|
116
|
+
#Used to indent GEDCOM output for pretty printing.
|
117
|
+
def tabstop(level)
|
118
|
+
#printing aid for indenting each level
|
119
|
+
return "" if !@@tabs || level <= 0
|
120
|
+
' ' * level
|
121
|
+
end
|
122
|
+
|
123
|
+
#Returns a GEDCOM line, with optional leading tabs.
|
124
|
+
def single_line(level, tag, data = nil)
|
125
|
+
#printing aid for tags that can have CONT or CONC sub-tags
|
126
|
+
s_out = "#{tabstop(level)}#{level} #{tag}"
|
127
|
+
if data != nil
|
128
|
+
data.each do |word|
|
129
|
+
if word != "\n"
|
130
|
+
s_out += " #{word}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
s_out += "\n"
|
135
|
+
end
|
136
|
+
|
137
|
+
#Returns a GEDCOM line for this tag, with CONC lines if the length
|
138
|
+
#of a line exceeds the GEDCOM standard line length.
|
139
|
+
#Recognises '\n' chars in the data and creates a CONT line after the '\n'
|
140
|
+
#Recognised @@tab to indent lines if pretty printing the output.
|
141
|
+
#Nb. Lots of GEDCOM files ignore the line lengths in the standard, so this
|
142
|
+
#method can created extra CONC lines in the output if a transmission is read
|
143
|
+
#then dumped again.
|
144
|
+
#The standard says that
|
145
|
+
#* Leading white space should be ignored, though a lot of systems can't cope with leading white space.
|
146
|
+
#* levels can be up to 2 digits (i.e. up to 99). 0 - 9 should not have a leading 0.
|
147
|
+
#* XREFs can be 20 chars plus 2 for the enclosing '@'s
|
148
|
+
#* GEDCOM tags can be 31 chars (though only 15 matter). No tag in the standard is bigger than 4 chars
|
149
|
+
#* The Line terminator can end in LF, CR LF, CR, LF CR.
|
150
|
+
#* The entire record should be no more than 32K, which mainly affects inline multimedia records.
|
151
|
+
#* Individual lines should not exceed 255 bytes (not chars). This is effectively a max line buffer size.
|
152
|
+
#* This includes the leading-space + level + delimiter + tag + delimiter + xref + delimiter + data-value + line-terminator.
|
153
|
+
#* Many data values have tag specific recommended lengths for use in fixed length data base schemas.
|
154
|
+
# These are usually much smaller than the line length would allow.
|
155
|
+
def cont_conc(level,tag, conc=nil, data = nil)
|
156
|
+
#printing aid for tags that can have CONT or CONC sub-tags
|
157
|
+
s_out = "#{tabstop(level)}#{level} #{tag}"
|
158
|
+
nlevel = level + (conc ? 0 : 1)
|
159
|
+
|
160
|
+
if data != nil
|
161
|
+
length = s_out.length
|
162
|
+
data.each_with_index do |word,i|
|
163
|
+
if length > 253 && word != "\n" && data.length != i #253 allows for CR LF or LF CR pairs as the line terminator.
|
164
|
+
s_tmp = "#{tabstop(nlevel)}#{nlevel} CONC"
|
165
|
+
length = s_tmp.length #new line, so reset length
|
166
|
+
s_out += "\n" + s_tmp
|
167
|
+
end
|
168
|
+
s_out += " #{word}"
|
169
|
+
if word == "\n"
|
170
|
+
s_tmp = "#{tabstop(nlevel)}#{nlevel} CONT" #Start a CONT line after the '\n'
|
171
|
+
length = s_tmp.length #new line, so reset length
|
172
|
+
s_out += s_tmp
|
173
|
+
else
|
174
|
+
length += word.length
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
s_out += "\n"
|
179
|
+
end
|
180
|
+
|
181
|
+
#Generate a Multimedia_record's Encoded_line_record.
|
182
|
+
#This is an inline Multimedia data source, rather than a file reference.
|
183
|
+
#The blob is stored internally as a multiline string. In the GEDCOM file
|
184
|
+
#a blob is stored as multiple GEDCOM lines. The first uses a BLOB tag.
|
185
|
+
#Subsequent lines use CONT tags.
|
186
|
+
def blob(level, data = nil)
|
187
|
+
#blobs only have CONT sub-tags
|
188
|
+
s_out = "#{tabstop(level)}#{level} CONT"
|
189
|
+
|
190
|
+
if data != nil
|
191
|
+
data.each_with_index do |word,i|
|
192
|
+
s_out += " #{word}"
|
193
|
+
if word == "\n"
|
194
|
+
s_out += "#{tabstop(level)}#{level} CONT"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
s_out += "\n"
|
199
|
+
end
|
200
|
+
|
201
|
+
#returns a XREF gedcom line.
|
202
|
+
#Level 0 GEDCOM has the @XREF@ before the tag.
|
203
|
+
#Level n GEDCOM records have the @XREF@ after the tag.
|
204
|
+
def xref(level, tag, xref)
|
205
|
+
if level == 0
|
206
|
+
"#{tabstop(level)}#{level} @#{xref}@ #{tag}\n"
|
207
|
+
else
|
208
|
+
"#{tabstop(level)}#{level} #{tag} @#{xref}@\n"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
#Process an instruction, defined by action, for this level, tag and data value
|
213
|
+
#The actions:
|
214
|
+
#* :xref indicates that we need to generate a GEDCOM line with an @XREF@ tag
|
215
|
+
#* :print indicates that we need to generate a non-XREF GEDCOM line
|
216
|
+
#* :conc indicates that this GEDCOM line can be split into multiple lines with CONC or CONT
|
217
|
+
# The first line output uses the tag, subsequent lines use CONC or CONT.
|
218
|
+
#* :cont indicates that this GEDCOM line con be split into multiple lines with CONC or CONT.
|
219
|
+
# This differs for :conc, in that the tags level starts at level+1, not at level.
|
220
|
+
#* :blob indicates the GEDCOM line can be split over multiple lines using just CONT tags.
|
221
|
+
# These occur in inline multimedia records.
|
222
|
+
#* :date outputs a GEDCOM date line from a Date_record
|
223
|
+
#* :time outputs a GEDCOM time line from a Time_record
|
224
|
+
#* :nodata indicates that only the level and tag need to output. There is no data value.
|
225
|
+
#* :walk indicates this item is a sub-record, therefore we need to recurse and process it using
|
226
|
+
# its action arrays, not this objects action arrays. These are the @this_level and @sub_level
|
227
|
+
# arrays, which are usually defined in the classes initialize method, but sometimes in a
|
228
|
+
# an object specific to_gedcom method.
|
229
|
+
def to_s_r_action(level, action, tag, data=nil)
|
230
|
+
case action
|
231
|
+
when :xref then
|
232
|
+
xref_check(level, tag, data[0], data[1])
|
233
|
+
xref(level, tag, data[1])
|
234
|
+
when :print then single_line(level, tag, data )
|
235
|
+
when :conc then cont_conc(level, tag, true, data )
|
236
|
+
when :cont then cont_conc(level, tag, false, data )
|
237
|
+
when :blob then blob(level, data )
|
238
|
+
when :walk then data.to_gedcom(level)
|
239
|
+
when :date then single_line(level, tag, data ) #fix later to format date records
|
240
|
+
when :time then single_line(level, tag, data ) #fix later to format time records
|
241
|
+
when :nodata then single_line(level, tag, nil )
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
protected
|
246
|
+
|
247
|
+
#validate that the record referenced by the XREF actually exists in this transmission.
|
248
|
+
#Genearte a warning if it does not. It does not stop the processing of this line.
|
249
|
+
def xref_check(level, tag, index, xref)
|
250
|
+
if @transmission != nil && @transmission.find(index, xref) == nil
|
251
|
+
#Warning message that reference points to an unknown target.
|
252
|
+
print "#{level+1} NOTE ****************Key not found: #{index} #{xref}\n"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
#to_s with the variable list (as symbols) passed to it in the order they are to be printed
|
257
|
+
def to_s_ordered(variable_list)
|
258
|
+
if variable_list != nil
|
259
|
+
s = ''
|
260
|
+
variable_list.each do |v|
|
261
|
+
s += "@#{v} = " + pv_byname(v) + "\n"
|
262
|
+
end
|
263
|
+
s
|
264
|
+
else
|
265
|
+
''
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
#recursive to_s. We want to print this object and its sub-records.
|
271
|
+
#the definition of how we want to print and when to recurse, is in the this_level and sub_level arrays.
|
272
|
+
#These have the form [ [ action, tag, data_source ],...] (see to_s_r_action )
|
273
|
+
def to_s_r(level = 0, this_level=[], sub_levels=[])
|
274
|
+
s_out = ""
|
275
|
+
this_level.each do |l|
|
276
|
+
this_level_instruction = Instruction.new(l)
|
277
|
+
if this_level_instruction.data != nil
|
278
|
+
data = self.send( this_level_instruction.data ) #gets the contents using the symbol, and sending "self" a message
|
279
|
+
else
|
280
|
+
data = [['']]
|
281
|
+
end
|
282
|
+
if data != nil #could be if the self.send targets a variable that doesn't exist.
|
283
|
+
data.each do |data_instance|
|
284
|
+
s_out += to_s_r_action(level, this_level_instruction.action, this_level_instruction.tag, data_instance)
|
285
|
+
|
286
|
+
sub_levels.each do |sl|
|
287
|
+
sub_level_instruction = Instruction.new(sl)
|
288
|
+
if sub_level_instruction.data != nil
|
289
|
+
sub_level_data = self.send( sub_level_instruction.data ) #gets the contents using the symbol, and sending "self" a message
|
290
|
+
else
|
291
|
+
sub_level_data = [['']]
|
292
|
+
end
|
293
|
+
if sub_level_data != nil #could be if the self.send targets a variable that doesn't exist.
|
294
|
+
sub_level_data.each do |sub_data_instance|
|
295
|
+
s_out += to_s_r_action(level+1, sub_level_instruction.action, sub_level_instruction.tag, sub_data_instance )
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
return s_out
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
|