class BlueButtonParser
Constants
- ALWAYS_SKIP_LINES
- DEFAULT_CONFIG
Attributes
config[R]
data[R]
text[R]
Public Class Methods
new(bb_data_text, config=DEFAULT_CONFIG, newline="\n")
click to toggle source
# File lib/blue_button_parser.rb, line 82 def initialize(bb_data_text, config=DEFAULT_CONFIG, newline="\n") @text = bb_data_text @config= config @data = parse_text(@text, newline) end
Private Instance Methods
column_widths(line, columns)
click to toggle source
# File lib/blue_button_parser.rb, line 207 def column_widths(line, columns) columns.collect{|c| line.index(c)} end
get_key_values(line, current_section)
click to toggle source
# File lib/blue_button_parser.rb, line 168 def get_key_values(line, current_section) key_values = get_multi_key_values(line, current_section) key_values = get_single_key_value(line) if key_values.nil? return key_values end
get_multi_key_values(line, current_section)
click to toggle source
# File lib/blue_button_parser.rb, line 132 def get_multi_key_values(line, current_section) key_values = nil if key_sets = sect_config(current_section, :same_line_keys) unless key_sets.first.is_a?(Array) key_sets = [key_sets] end key_sets.each do |keys| regexp_str = keys.collect{|k| "#{k}: (.*)"}.join regexp = Regexp.new(regexp_str) if keys_match = line.match(regexp) key_values = Hash.new keys.each_with_index do |key, index| key_values[key] = keys_match[index + 1] end break end end end return key_values end
get_single_key_value(line)
click to toggle source
# File lib/blue_button_parser.rb, line 156 def get_single_key_value(line) if key_match = line.match(/(.*)\: (.*)?/) key_values = {key_match[1] => key_match[2]} elsif key_match = line.match(/(.*):$/) key_values = {key_match[1] => nil} else key_values = nil end return key_values end
key_ended?(line)
click to toggle source
# File lib/blue_button_parser.rb, line 174 def key_ended?(line) # either an empty line or a line starting with a key (e.g. "Status:") means we're done with multi-line line.empty? or line.match(/^\S(.*): (\S*)/) end
new_collection?(line, last_line, current_section)
click to toggle source
# File lib/blue_button_parser.rb, line 96 def new_collection?(line, last_line, current_section) new_collection = nil if collections = sect_config(current_section, :collection) collections.each_pair do |name, collection_config| if starts_with = collection_config[:item_starts_with] if line.match(Regexp.new("^#{starts_with}:")) new_collection = name break end elsif table_columns = collection_config[:table_columns] new_table = false if table_starts_with = collection_config[:table_starts_with] if last_line.match(Regexp.new("^#{table_starts_with}")) new_table = true end else new_table = true end if new_table regexp_str = ".?#{table_columns.join('.*')}.?" if line.match(Regexp.new(regexp_str)) new_collection = name break end end end end end return new_collection end
new_section?(line)
click to toggle source
# File lib/blue_button_parser.rb, line 90 def new_section?(line) new_section = line.match(/^[-]+ (.*) [-]+/) new_section = new_section[1] if new_section return new_section end
parse_table_line(line, columns, column_widths)
click to toggle source
# File lib/blue_button_parser.rb, line 187 def parse_table_line(line, columns, column_widths) row = Hash.new columns.each_with_index do |column, index| start = column_widths[index] finish = if index == column_widths.size - 1 line.size else column_widths[index + 1] end val_str = (line[start, finish-start]).strip val_str = val_str.empty? ? nil : val_str row[column] = val_str end return row end
parse_text(text, newline="\n")
click to toggle source
# File lib/blue_button_parser.rb, line 211 def parse_text(text, newline="\n") # parse text line by line lines = text.split(newline) # state variables current_section = nil current_collection = nil current_key = nil current_table = nil # put parsed data into this hash data = Hash.new # start parsing lines.each_with_index do |line, index| skip_regexps = (ALWAYS_SKIP_LINES + (sect_config(current_section, :skip_lines) || [])).compact skip_regexps = skip_regexps.collect{|r| Regexp.new(r)} next if skip_regexps.find{|re| re.match(line)} if collection = new_collection?(line, lines[index - 1], current_section) current_collection = collection current_key = nil data[current_section][current_collection] ||= [] if columns = table_columns(current_section, current_collection) current_table = {:columns => columns, :widths => column_widths(line, columns)} next else data[current_section][current_collection] << Hash.new end end if key_ended?(line) current_key = nil end if current_section and current_key value = line.rstrip if current_collection.nil? data[current_section][current_key] = [data[current_section][current_key], value].compact.join(" \n") else (data[current_section][current_collection].last)[current_key] = [(data[current_section][current_collection].last)[current_key], value].compact.join(" \n") end end if section = new_section?(line) current_section = section current_collection = nil data[current_section] ||= {} elsif current_table if line.empty? current_collection = nil current_table = nil else data[current_section][current_collection] << parse_table_line(line, current_table[:columns], current_table[:widths]) end elsif (!current_key and current_section and key_values = get_key_values(line, current_section)) key_values.each_pair do |key, value| val = (value.nil? or value.strip.empty?) ? nil : value.strip #empty strings should be converted to nils if current_collection.nil? data[current_section][key] = val else (data[current_section][current_collection].last)[key] = val end current_key = key end end end return data end
sect_config(current_section, key)
click to toggle source
# File lib/blue_button_parser.rb, line 179 def sect_config(current_section, key) if @config[current_section] @config[current_section][key] else nil end end
table_columns(current_section, current_collection)
click to toggle source
# File lib/blue_button_parser.rb, line 203 def table_columns(current_section, current_collection) sect_config(current_section, :collection)[current_collection][:table_columns] end