Class: Webby::Resources::MetaFile
- Inherits:
-
Object
- Object
- Webby::Resources::MetaFile
- Defined in:
- lib/webby/resources/meta_file.rb
Overview
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.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- META_SEP =
:nodoc:
%r/\A---\s*(?:\r\n|\n)?\z/
- ERR_MSG =
:nodoc:
"corrupt meta-data (perhaps there is an errant YAML marker '---' in the file)"
Class Method Summary collapse
-
.meta_data(name) ⇒ Object
call-seq: MetaFile.meta_data( filename ) => object or nil.
-
.meta_data?(name) ⇒ Boolean
call-seq: MetaFile.meta_data?( filename ) => true or false.
-
.read(name) ⇒ Object
call-seq: MetaFile.read( filename ) => string.
Instance Method Summary collapse
-
#each ⇒ Object
Reads in each meta-data section and yields it to the given block.
-
#initialize(io) ⇒ MetaFile
constructor
Creates a new MetaFile parser that will read from the given io stream.
-
#meta_count ⇒ Object
Returns the number of meta-data blocks at the top of the file.
-
#meta_data ⇒ Object
Returns the meta-data defined at the top of the file.
-
#meta_data? ⇒ Boolean
Returns true if the IO stream contains meta-data.
-
#meta_end ⇒ Object
Returns the position in the IO stream where the meta-data ends and the regular data begins.
-
#read ⇒ Object
Returns the entire contents of the IO stream exluding any meta-data found at the beginning of the stream.
Constructor Details
#initialize(io) ⇒ MetaFile
Creates a new MetaFile parser that will read from the given io stream.
67 68 69 70 71 |
# 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 |
Class Method Details
.meta_data(name) ⇒ Object
call-seq:
MetaFile.( filename ) => object or nil
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.
50 51 52 |
# File 'lib/webby/resources/meta_file.rb', line 50 def self.( name ) ::File.open(name, 'r') {|fd| MetaFile.new(fd).} end |
.meta_data?(name) ⇒ Boolean
call-seq:
MetaFile.( filename ) => true or false
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.
61 62 63 |
# File 'lib/webby/resources/meta_file.rb', line 61 def self.( name ) ::File.open(name, 'r') {|fd| MetaFile.new(fd).} end |
.read(name) ⇒ Object
call-seq:
MetaFile.read( filename ) => string
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.
39 40 41 |
# File 'lib/webby/resources/meta_file.rb', line 39 def self.read( name ) ::File.open(name, 'r') {|fd| MetaFile.new(fd).read} end |
Instance Method Details
#each ⇒ Object
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 …
.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.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/webby/resources/meta_file.rb', line 126 def each return unless 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. raise Error, msg end |
#meta_count ⇒ Object
Returns the number of meta-data blocks at the top of the file.
176 177 178 179 |
# File 'lib/webby/resources/meta_file.rb', line 176 def @meta_count end |
#meta_data ⇒ Object
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.
160 161 162 163 164 165 |
# File 'lib/webby/resources/meta_file.rb', line 160 def return if .nil? @io.seek 0 return YAML.load(@io) end |
#meta_data? ⇒ Boolean
Returns true if the IO stream contains meta-data. Returns false if the IO stream does not contain meta-data.
170 171 172 |
# File 'lib/webby/resources/meta_file.rb', line 170 def .nil? ? false : true end |
#meta_end ⇒ Object
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
.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/webby/resources/meta_file.rb', line 184 def 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 |
#read ⇒ Object
Returns the entire contents of the IO stream exluding any meta-data found at the beginning of the stream.
76 77 78 79 80 81 |
# File 'lib/webby/resources/meta_file.rb', line 76 def read count = @io.seek 0 count.times {@io.gets} unless count.nil? @io.read end |