lib/metaheader.rb in metaheader-1.3beta1 vs lib/metaheader.rb in metaheader-1.3beta2

- old
+ new

@@ -41,11 +41,11 @@ # Create a new instance from the contents of a file. # @param path [String] path to the file to be read # @return [MetaHeader] def self.from_file(path) - self.new File.read(path) + File.open(path) {|file| self.new file } end # Construct a new MetaHeader object or return the object untouched # @param input [String, MetaHeader] # @return [MetaHeader] @@ -56,27 +56,27 @@ self.new input end end # Parse every tags found in input up to the first newline. - # @param input [String] + # @param input [String, IO] def initialize(input) @strict = false @data = {} @last_key = nil + @empty_lines = 0 - input = input.encode universal_newline: true - input.each_line {|line| - if line.strip.empty? - break - else - parse line - end - } + unless input.is_a? IO + input = StringIO.new input.encode universal_newline: true + end + input.each_line {|line| break unless parse line } + Parser.each {|klass| + input.rewind + parser = klass.new parser.instance_variable_set :@mh, self parser.parse input } end @@ -196,29 +196,31 @@ private # @api private Tag = Struct.new :name, :value REGEX = /\A(?<prefix>.*?) - (?:@(?<key>\w+)|(?<key>[\w][\w\s]*?)\s*:) - (?:\s+(?<value>[^\n]+))? + (?:@(?<key>\w+)|(?<key>[\w][\w\s]*?)\s*(?<alt>:)) + (?:\s*(?<value>[^\n]+))? \Z/x.freeze def parse(line) line.chomp! # multiline value must have the same line prefix as the key if @last_key && line.start_with?(@last_prefix.rstrip) if append line - return + return true else @last_key = nil end end line.rstrip! - return unless match = REGEX.match(line) + return false if @empty_lines > 0 + return !line.empty? unless match = REGEX.match(line) + return true if match[:alt] && match[:value].nil? # single line @last_prefix = match[:prefix] key = match[:key].downcase.gsub(/[^\w]/, '_') @@ -229,12 +231,14 @@ @data[@last_key] = Tag.new match[:key].freeze, value @line_breaks = 0 end def append(line) - if line.rstrip == @last_prefix.rstrip + prefix = line.rstrip + if prefix == @last_prefix.rstrip @line_breaks += 1 + @empty_lines += 1 if prefix.empty? return true # add the line break later elsif line.start_with? @last_prefix mline = line[@last_prefix.size..-1] stripped = mline.lstrip indent_level = mline.index stripped @@ -246,10 +250,10 @@ tag = @data[@last_key] tag.value = @raw_value.to_s unless tag.value.is_a? String @line_breaks += 1 unless tag.value.empty? tag.value += "\n" * @line_breaks - @line_breaks = 0 + @line_breaks = @empty_lines = 0 tag.value += stripped stripped end