The MetaFile class is used to read meta-data and content from files. The meta-data is in a YAML block located at the top of the file. The content is the remainder of the file (everything after the YAML block).
The meta-data data must be found between two YAML block separators “—”, each on their own line.
Example:
--- layout: blog filter: markdown tags: - ruby - web development --- This is a blog entry formatted using MarkDown and tagged as "ruby" and "web development". The layout being used is the "blog" format.
Reads in each meta-data section and yields it to the given block. The first meta-data section is yielded “as is”, but subsequent meta-data sections are merged with this first section and then yielded. This allows the user to define common items in the first meta-data section and only include items that are different in the subsequent sections.
Example:
--- title: First Title author: me directory: foo/bar/baz --- title: Second Title author: you --- title: Third Title author: them ---
and parsing the meta-data above yields …
meta_file.each do |hash| pp hash end
the following output
{ 'title' => 'First Title', 'author' => 'me', 'directory' => 'foo/bar/baz' } { 'title' => 'Second Title', 'author' => 'you', 'directory' => 'foo/bar/baz' } { 'title' => 'Third Title', 'author' => 'them', 'directory' => 'foo/bar/baz' }
Even though the “directory” item only appears in the first meta-data block, it is copied to all the subsequent blocks.
# File lib/webby/resources/meta_file.rb, line 126 def each return unless meta_data? first, count = nil, 0 @io.seek 0 buffer = @io.gets while count < @meta_count while (line = @io.gets) !~ META_SEP buffer << line end h = YAML.load(buffer) raise Error, ERR_MSG unless h.instance_of?(Hash) if first then h = first.merge(h) else first = h.dup end buffer = line count += 1 yield h end rescue ArgumentError => err msg = ERR_MSG.dup << "\n\t-- " << err.message raise Error, msg end
Returns the number of meta-data blocks at the top of the file.
# File lib/webby/resources/meta_file.rb, line 176 def meta_count meta_end @meta_count end
Returns the meta-data defined at the top of the file. Returns
nil
if no meta-data is defined. The meta-data is returned as
Ruby objects
Meta-data is stored in YAML format between two YAML separators “—” on their own lines.
# File lib/webby/resources/meta_file.rb, line 160 def meta_data return if meta_end.nil? @io.seek 0 return YAML.load(@io) end
Returns true if the IO stream contains meta-data. Returns false if the IO stream does not contain meta-data.
# File lib/webby/resources/meta_file.rb, line 170 def meta_data? meta_end.nil? ? false : true end
Returns the position in the IO stream where the meta-data ends and the
regular data begins. If there is no meta-data in the stream, returns
nil
.
# File lib/webby/resources/meta_file.rb, line 184 def meta_end return @meta_end if defined? @meta_end @meta_end = nil @io.seek 0 line = @io.read(4) return unless META_SEP =~ line @io.seek 0 @io.gets pos, count = nil, 1 while line = @io.gets count += 1 if META_SEP =~ line pos = count @meta_count += 1 end end return if pos.nil? @meta_end = pos end
Returns the entire contents of the IO stream exluding any meta-data found at the beginning of the stream.
# File lib/webby/resources/meta_file.rb, line 76 def read count = meta_end @io.seek 0 count.times {@io.gets} unless count.nil? @io.read end
Opens the file identified by filename and returns the meta-data
located at the top of the file. If the file contains no meta-data, then
nil
is returned.
# File lib/webby/resources/meta_file.rb, line 50 def self.meta_data( name ) ::File.open(name, 'r') {|fd| MetaFile.new(fd).meta_data} end
Opens the file identified by filename and returns true if there is a meta-data block at the top of the file, and returns false if there is not a meta-data block at the top of the file.
# File lib/webby/resources/meta_file.rb, line 61 def self.meta_data?( name ) ::File.open(name, 'r') {|fd| MetaFile.new(fd).meta_data?} end
Creates a new MetaFile parser that will read from the given io stream.
# File lib/webby/resources/meta_file.rb, line 67 def initialize( io ) raise ArgumentError, "expecting an IO stream" unless io.respond_to? :gets @io = io @meta_count = 0 end
Opens the file identified by filename and returns the contents of the file as a string. Any meta-data at the top of the file is skipped and is not included in the returned string. If the file contains no meta-data, then this method behaves the same as File#read.
# File lib/webby/resources/meta_file.rb, line 39 def self.read( name ) ::File.open(name, 'r') {|fd| MetaFile.new(fd).read} end