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