class GEDCOM::Parser
Constants
- ANY
Attributes
auto_concat[RW]
callbacks[R]
Public Class Methods
new(&block)
click to toggle source
# File lib/gedcom_ruby.rb, line 32 def initialize(&block) @callbacks = { :before => {}, :after => {} } @context_stack = [] @data_stack = [] @current_level = -1 @auto_concat = true instance_eval(&block) if block_given? after_initialize end
Public Instance Methods
after(tags, callback=nil, &block)
click to toggle source
# File lib/gedcom_ruby.rb, line 61 def after(tags, callback=nil, &block) tags = [tags].flatten callback = check_proc_or_block(callback, &block) @callbacks[:after][tags] = default_empty(@callbacks[:after][tags]) @callbacks[:after][tags].push(callback) end
after_initialize()
click to toggle source
# File lib/gedcom_ruby.rb, line 49 def after_initialize # Template end
before(tags, callback=nil, &block)
click to toggle source
# File lib/gedcom_ruby.rb, line 53 def before(tags, callback=nil, &block) tags = [tags].flatten callback = check_proc_or_block(callback, &block) @callbacks[:before][tags] = default_empty(@callbacks[:before][tags]) @callbacks[:before][tags].push(callback) end
context()
click to toggle source
# File lib/gedcom_ruby.rb, line 84 def context @context_stack end
parse(file)
click to toggle source
# File lib/gedcom_ruby.rb, line 69 def parse(file) case file when String if file =~ /\n/mo parse_string(file) else parse_file(file) end when IO parse_io(file) else raise ArgumentError.new("requires a String or IO") end end
Protected Instance Methods
check_proc_or_block(proc, &block)
click to toggle source
# File lib/gedcom_ruby.rb, line 95 def check_proc_or_block(proc, &block) unless proc or block_given? raise ArgumentError.new("proc or block required") end proc = method(proc) if proc.kind_of? Symbol proc ||= Proc.new(&block) end
concat_data(tag, rest)
click to toggle source
# File lib/gedcom_ruby.rb, line 147 def concat_data(tag, rest) rest = rest || "" # Handle nil case @data_stack[-1] = case when @data_stack.last.empty? then rest when @context_stack.last == 'BLOB' then "#{@data_stack.last}#{rest}" when tag == 'CONT' then "#{@data_stack.last}\n#{rest}" when tag == 'CONC' then "#{@data_stack.last}#{rest}" end end
default_empty(arr)
click to toggle source
# File lib/gedcom_ruby.rb, line 91 def default_empty(arr) arr || [] end
do_callbacks(context_sym, tags, data)
click to toggle source
# File lib/gedcom_ruby.rb, line 157 def do_callbacks(context_sym, tags, data) return if tags == [] tag_cbs = default_empty(@callbacks[context_sym][tags]) any_cbs = default_empty(@callbacks[context_sym][ANY]) relevant_callbacks = tag_cbs + any_cbs relevant_callbacks.each do |callback| callback.call(data) end end
parse_file(file)
click to toggle source
# File lib/gedcom_ruby.rb, line 103 def parse_file(file) File.open(file) do |io| parse_io(io) end end
parse_io(io)
click to toggle source
# File lib/gedcom_ruby.rb, line 113 def parse_io(io) io.each_line do |line| line = line.rstrip! next if line.empty? level, tag, rest = line.match(/^(\d) (\S+) ?(.*)$/).captures level = level.to_i if (tag == 'CONT' || tag == 'CONC') and @auto_concat concat_data(tag, rest) next end unwind_to(level) tag, rest = rest, tag if tag =~ /@.*@/ @context_stack.push(tag) @data_stack.push(rest) @current_level = level do_callbacks(:before, @context_stack, rest) end unwind_to(-1) end
parse_string(str)
click to toggle source
# File lib/gedcom_ruby.rb, line 109 def parse_string(str) parse_io(StringIO.new(str)) end
unwind_to(level)
click to toggle source
# File lib/gedcom_ruby.rb, line 138 def unwind_to(level) while @current_level >= level do_callbacks(:after, @context_stack, @data_stack.last) @context_stack.pop @data_stack.pop @current_level -= 1 end end