maneki 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +105 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/lib/maneki.rb +241 -0
- data/maneki.gemspec +58 -0
- data/test/chapter.rb +3 -0
- data/test/content/chapters/01-the-first-chapter.text +3 -0
- data/test/content/chapters/02-chapter-2.text +3 -0
- data/test/content/chapters/03-chapter-with-headers.text +8 -0
- data/test/content/chapters/04-different-chapter.text +6 -0
- data/test/content/documents/first-document.text +6 -0
- data/test/content/documents/second-document.text +3 -0
- data/test/content/documents/third-document.text +3 -0
- data/test/test_all.rb +5 -0
- data/test/test_chapters.rb +50 -0
- data/test/test_maneki.rb +36 -0
- metadata +80 -0
data/README.markdown
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
Maneki
|
2
|
+
======
|
3
|
+
|
4
|
+
Maneki is a simple file-based model for your Ruby projects. Give it a directory and it will parse any relevant files within.
|
5
|
+
|
6
|
+
For example you might have a model like this:
|
7
|
+
|
8
|
+
class Document < Maneki
|
9
|
+
path_is '../content/documents'
|
10
|
+
end
|
11
|
+
|
12
|
+
...and a directory, `documents`, that contains a bunch of markdown documents:
|
13
|
+
|
14
|
+
documents/
|
15
|
+
first-document.text
|
16
|
+
second-document.text
|
17
|
+
third-document.text
|
18
|
+
|
19
|
+
...and each file might be in a form similar to:
|
20
|
+
|
21
|
+
# This is the title
|
22
|
+
|
23
|
+
- published: yes
|
24
|
+
- authors: Aristoclea Cattington, Sebastian Fluffybottom
|
25
|
+
|
26
|
+
This is the content of the document. It is written in Markdown.
|
27
|
+
|
28
|
+
This example parsed document would have the following properties:
|
29
|
+
|
30
|
+
- Title: This is the title
|
31
|
+
- Headers:
|
32
|
+
- Published: True
|
33
|
+
- Authors:
|
34
|
+
- 'Aristoclea Cattington'
|
35
|
+
- 'Sebastian Fluffybottom'
|
36
|
+
- Body: This is the content of the document. It is written in Markdown.
|
37
|
+
|
38
|
+
|
39
|
+
Getting some documents
|
40
|
+
----------------------
|
41
|
+
|
42
|
+
If you want all of the documents.
|
43
|
+
|
44
|
+
Document.all
|
45
|
+
|
46
|
+
Or you can find items by their slug.
|
47
|
+
|
48
|
+
Document.find :slug => 'test-document'
|
49
|
+
|
50
|
+
Or you can also search for the inclusion of certain headers.
|
51
|
+
|
52
|
+
Document.find :headers => { :published => true }
|
53
|
+
Document.find :headers => { :authors => 'Aristoclea Cattington' }
|
54
|
+
|
55
|
+
You can also grab any documents from a given category (read on).
|
56
|
+
|
57
|
+
|
58
|
+
Document categories
|
59
|
+
-------------------
|
60
|
+
|
61
|
+
If documents are found within folders then they will also be added to a categorised list.
|
62
|
+
|
63
|
+
For example, given this directory structure:
|
64
|
+
|
65
|
+
content/
|
66
|
+
documents/
|
67
|
+
first-document.text
|
68
|
+
second-document.text
|
69
|
+
third-document.text
|
70
|
+
projects/
|
71
|
+
a-project.text
|
72
|
+
here-is-another-project.text
|
73
|
+
|
74
|
+
Now assume that Maneki has its path set to `content`:
|
75
|
+
|
76
|
+
Maneki.path = 'content'
|
77
|
+
|
78
|
+
Here if we want to grab any posts we can just ask for the category.
|
79
|
+
|
80
|
+
Maneki.documents
|
81
|
+
|
82
|
+
Here we will get:
|
83
|
+
|
84
|
+
- First document
|
85
|
+
- Second document
|
86
|
+
- Third document
|
87
|
+
|
88
|
+
Whereas if you did:
|
89
|
+
|
90
|
+
Maneki.projects
|
91
|
+
|
92
|
+
You would get:
|
93
|
+
|
94
|
+
- A Project
|
95
|
+
- Here is another project
|
96
|
+
|
97
|
+
If you want to get a list of the found categories then ask for it.
|
98
|
+
|
99
|
+
Maneki.categories
|
100
|
+
|
101
|
+
|
102
|
+
Suggestions?
|
103
|
+
------------
|
104
|
+
|
105
|
+
[Find me on Twitter](http://twitter.com/nathanhoad)
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
task :default => :test
|
2
|
+
|
3
|
+
|
4
|
+
### TESTING ###
|
5
|
+
desc 'Run unit tests'
|
6
|
+
task 'test' do |t|
|
7
|
+
sh 'ruby test/test_all.rb'
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
### PACKAGING ###
|
12
|
+
begin
|
13
|
+
require 'jeweler'
|
14
|
+
Jeweler::Tasks.new do |gemspec|
|
15
|
+
gemspec.name = "maneki"
|
16
|
+
gemspec.summary = "A simple file-based model for your Ruby projects"
|
17
|
+
gemspec.description = "Maneki loads and parses any relevant text files in a given directory"
|
18
|
+
gemspec.email = "nathan@nathanhoad.net"
|
19
|
+
gemspec.homepage = "http://github.com/nathanhoad/maneki"
|
20
|
+
gemspec.authors = ["Nathan Hoad"]
|
21
|
+
gemspec.files = `git ls-files`.split("\n").sort.reject{ |file| file =~ /^\./ }
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
### DOCUMENTATION ###
|
29
|
+
require 'rake/rdoctask'
|
30
|
+
Rake::RDocTask.new do |rdoc|
|
31
|
+
if File.exist? 'VERSION'
|
32
|
+
version = File.read('VERSION')
|
33
|
+
else
|
34
|
+
version = ""
|
35
|
+
end
|
36
|
+
|
37
|
+
rdoc.rdoc_dir = 'rdoc'
|
38
|
+
rdoc.title = "Maneki #{version}"
|
39
|
+
rdoc.rdoc_files.include('README*')
|
40
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
41
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/lib/maneki.rb
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
# = Maneki
|
2
|
+
#
|
3
|
+
# Load documents from a directory and parse them. The idea is that
|
4
|
+
# any of the given documents (Markdown only for now) should be readable
|
5
|
+
# in their own format without parsing but be formatted in such way as
|
6
|
+
# to present meta information (title, headers, etc) in an easily parsable
|
7
|
+
# way.
|
8
|
+
class Maneki
|
9
|
+
# Set the search path
|
10
|
+
def self.path= (value)
|
11
|
+
path value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Set or return the search path
|
15
|
+
def self.path (value = nil)
|
16
|
+
@path = value if value
|
17
|
+
@category = File.basename(value) unless @category
|
18
|
+
@path
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
# Set the general category for these documents
|
23
|
+
def self.category (value = nil)
|
24
|
+
@category = value
|
25
|
+
@category
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Get a list of all categories
|
30
|
+
def self.categories
|
31
|
+
prepare
|
32
|
+
@categorised.keys
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Grab all documents
|
37
|
+
def self.all
|
38
|
+
prepare
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Search for any documents
|
43
|
+
def self.find (args = {})
|
44
|
+
if args[:slug] or args.is_a? String
|
45
|
+
return find_by_slug(args[:slug] || args)
|
46
|
+
end
|
47
|
+
|
48
|
+
match = args[:match] || :any
|
49
|
+
args.delete(:match)
|
50
|
+
|
51
|
+
all.select do |item|
|
52
|
+
matches = 0
|
53
|
+
|
54
|
+
if args[:title]
|
55
|
+
if item.title == args[:title]
|
56
|
+
matched ||= true if match == :any
|
57
|
+
matches += 1 if match == :all
|
58
|
+
else
|
59
|
+
matched ||= false if match == :all
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if args[:body]
|
64
|
+
if item.body.downcase.include? args[:body].downcase
|
65
|
+
matched ||= true if match == :any
|
66
|
+
matches += 1 if match == :all
|
67
|
+
else
|
68
|
+
matched ||= false if match == :all
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if args[:headers]
|
73
|
+
args[:headers].each_pair do |header, value|
|
74
|
+
if item.headers[header] and (item.headers[header] == value or item.headers[header].include? value)
|
75
|
+
matched ||= true if match == :any
|
76
|
+
matches += 1 if match == :all
|
77
|
+
else
|
78
|
+
matched ||= false if match == :all
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
matched || (matches >= args.size)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# The previous document before a given document
|
89
|
+
def self.previous_before (document, args = {})
|
90
|
+
prepare
|
91
|
+
if args[:category]
|
92
|
+
index = @categorised[args[:category]].index(document)
|
93
|
+
else
|
94
|
+
index = @documents.index(document)
|
95
|
+
end
|
96
|
+
@documents[index - 1] unless index == 0
|
97
|
+
end
|
98
|
+
|
99
|
+
# The next document after a given document
|
100
|
+
def self.next_after (document, args = {})
|
101
|
+
prepare
|
102
|
+
if args[:category]
|
103
|
+
index = @categorised[args[:category]].index(document)
|
104
|
+
else
|
105
|
+
index = @documents.index(document)
|
106
|
+
end
|
107
|
+
@documents[index + 1] unless index == @documents.length
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# Look up a document category
|
112
|
+
def self.method_missing (method, *args)
|
113
|
+
prepare
|
114
|
+
@categorised[method.to_s] unless @categorised.nil?
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
attr_accessor :filename, :category, :slug, :headers, :title, :body
|
119
|
+
|
120
|
+
# Create a new document
|
121
|
+
def initialize (args = {})
|
122
|
+
@filename = File.expand_path(args[:filename])
|
123
|
+
|
124
|
+
@body = ''
|
125
|
+
if File.exists? @filename
|
126
|
+
@category = File.dirname(@filename).split('/').last unless @category
|
127
|
+
@slug = @filename.gsub(File.expand_path(self.class.path) + '/', '').gsub(/\..+$/, '')
|
128
|
+
|
129
|
+
body = File.open(@filename).readlines
|
130
|
+
body.each do |line|
|
131
|
+
line.gsub!("\r", '') # fix up any DOS EOLs
|
132
|
+
end
|
133
|
+
|
134
|
+
title = body.find { |item| /^\#.+/.match item }
|
135
|
+
body = body[2..body.length-1] if title # consume title
|
136
|
+
|
137
|
+
# check for headers
|
138
|
+
@headers = Hash.new
|
139
|
+
if /^\s?\-.+/.match(body[0])
|
140
|
+
headers_end = body.index("\n") || 1
|
141
|
+
headers = body[0..headers_end-1] if headers_end # next blank line is end of headers
|
142
|
+
|
143
|
+
body_start = 1
|
144
|
+
body_start = body.index(headers.last) + 1 if headers
|
145
|
+
body = body[body_start..body.length - 1] if title
|
146
|
+
|
147
|
+
headers.each do |header|
|
148
|
+
unless header.strip == '' or /^\#.+/.match header
|
149
|
+
values = header.gsub(/^\s?\-/, '').strip.split(/:\s/)
|
150
|
+
key = values.shift.downcase.gsub(/[^\w\_]+/, '_').to_sym
|
151
|
+
value = values.join(': ').strip
|
152
|
+
# check for special header values (true, false, lists, etc)
|
153
|
+
if ['true', 't', 'yes', 'y'].include? value
|
154
|
+
value = true
|
155
|
+
elsif ['false', 'f', 'no', 'n'].include? value
|
156
|
+
value = false
|
157
|
+
elsif value.include? ','
|
158
|
+
value = value.split(/\,\s?/)
|
159
|
+
end
|
160
|
+
@headers[key] = value
|
161
|
+
end
|
162
|
+
end if headers
|
163
|
+
end
|
164
|
+
|
165
|
+
# title
|
166
|
+
@title = title.gsub(/^\#\s/, '').strip if title
|
167
|
+
|
168
|
+
# content
|
169
|
+
@body = body.join("").strip
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
# A callback to see if this document should be added to the list
|
175
|
+
def valid?
|
176
|
+
true
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
# Documents are the same if their IDs are the same
|
181
|
+
def == (rhs)
|
182
|
+
@slug == rhs.slug
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
# Sort by filename
|
187
|
+
def <=> (rhs)
|
188
|
+
@filename <=> rhs.filename
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
# Stringify this document
|
193
|
+
def to_s
|
194
|
+
title
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
protected
|
199
|
+
|
200
|
+
# Grab the @path with a slash if needed
|
201
|
+
def self.path_with_slash
|
202
|
+
files_path = File.expand_path(@path)
|
203
|
+
files_path += '/' unless files_path.end_with? '/'
|
204
|
+
files_path
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
# Find a document by its slug
|
209
|
+
def self.find_by_slug (slug)
|
210
|
+
filename = path_with_slash + slug + '.text'
|
211
|
+
if File.exists? filename
|
212
|
+
document = new(:filename => filename)
|
213
|
+
document if document.valid?
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
# Load the any documents in the files path
|
219
|
+
def self.prepare (args = {})
|
220
|
+
if @documents.nil? or args[:force]
|
221
|
+
files_path = path_with_slash
|
222
|
+
|
223
|
+
@documents = []
|
224
|
+
@categorised = {}
|
225
|
+
|
226
|
+
# find some documents
|
227
|
+
Dir.glob(["#{files_path}*", "#{files_path}*/*"]).each do |filename|
|
228
|
+
if filename.split('.').last == 'text'
|
229
|
+
document = new(:filename => filename)
|
230
|
+
if document.valid?
|
231
|
+
@documents << document
|
232
|
+
@categorised[document.category] ||= []
|
233
|
+
@categorised[document.category] << document
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
@documents.sort!
|
238
|
+
end
|
239
|
+
@documents
|
240
|
+
end
|
241
|
+
end
|
data/maneki.gemspec
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{maneki}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Nathan Hoad"]
|
12
|
+
s.date = %q{2010-05-22}
|
13
|
+
s.description = %q{Maneki loads and parses any relevant text files in a given directory}
|
14
|
+
s.email = %q{nathan@nathanhoad.net}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.markdown"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.markdown",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"lib/maneki.rb",
|
23
|
+
"maneki.gemspec",
|
24
|
+
"test/chapter.rb",
|
25
|
+
"test/content/chapters/01-the-first-chapter.text",
|
26
|
+
"test/content/chapters/02-chapter-2.text",
|
27
|
+
"test/content/chapters/03-chapter-with-headers.text",
|
28
|
+
"test/content/chapters/04-different-chapter.text",
|
29
|
+
"test/content/documents/first-document.text",
|
30
|
+
"test/content/documents/second-document.text",
|
31
|
+
"test/content/documents/third-document.text",
|
32
|
+
"test/test_all.rb",
|
33
|
+
"test/test_chapters.rb",
|
34
|
+
"test/test_maneki.rb"
|
35
|
+
]
|
36
|
+
s.homepage = %q{http://github.com/nathanhoad/maneki}
|
37
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
38
|
+
s.require_paths = ["lib"]
|
39
|
+
s.rubygems_version = %q{1.3.6}
|
40
|
+
s.summary = %q{A simple file-based model for your Ruby projects}
|
41
|
+
s.test_files = [
|
42
|
+
"test/chapter.rb",
|
43
|
+
"test/test_all.rb",
|
44
|
+
"test/test_chapters.rb",
|
45
|
+
"test/test_maneki.rb"
|
46
|
+
]
|
47
|
+
|
48
|
+
if s.respond_to? :specification_version then
|
49
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
50
|
+
s.specification_version = 3
|
51
|
+
|
52
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
53
|
+
else
|
54
|
+
end
|
55
|
+
else
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
data/test/chapter.rb
ADDED
data/test/test_all.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/maneki'
|
3
|
+
require File.dirname(__FILE__) + '/chapter'
|
4
|
+
|
5
|
+
|
6
|
+
class TestChapters < Test::Unit::TestCase
|
7
|
+
def test_document_load
|
8
|
+
chapter = Chapter.new :filename => File.dirname(__FILE__) + '/content/chapters/01-the-first-chapter.text'
|
9
|
+
assert_kind_of Chapter, chapter
|
10
|
+
assert_equal '01-the-first-chapter', chapter.slug
|
11
|
+
assert_equal 'Chapter 1: The first chapter', chapter.title
|
12
|
+
assert_equal 'This is the content of this chapter.', chapter.body
|
13
|
+
assert_equal({}, chapter.headers)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_chapters_load
|
17
|
+
assert_not_equal 0, Chapter.all.size
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_find
|
21
|
+
chapter = Chapter.find '01-the-first-chapter'
|
22
|
+
assert_kind_of Chapter, chapter
|
23
|
+
assert_equal 'Chapter 1: The first chapter', chapter.title
|
24
|
+
|
25
|
+
chapters = Chapter.find :headers => { :boolean_value => true }, :body => 'some headers', :match => :all
|
26
|
+
assert_equal 1, chapters.size
|
27
|
+
|
28
|
+
chapters = Chapter.find :headers => { :boolean_value => true }, :body => 'some headers', :match => :any
|
29
|
+
assert_equal 2, chapters.size
|
30
|
+
|
31
|
+
chapters = Chapter.find :headers => { :boolean_value => true }
|
32
|
+
assert_not_equal 0, chapters.size
|
33
|
+
|
34
|
+
chapters = Chapter.find :headers => { :list_values => 'are' }
|
35
|
+
assert_not_equal 0, chapters.size
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_headers
|
39
|
+
chapter = Chapter.find '01-the-first-chapter'
|
40
|
+
assert_equal({}, chapter.headers)
|
41
|
+
|
42
|
+
chapter = Chapter.find '03-chapter-with-headers'
|
43
|
+
assert_not_equal({}, chapter.headers)
|
44
|
+
assert_equal 'Here is a chapter written by a guest author. It has some headers.', chapter.body
|
45
|
+
|
46
|
+
assert_kind_of Array, chapter.headers[:list_values]
|
47
|
+
assert_kind_of TrueClass, chapter.headers[:boolean_value]
|
48
|
+
assert_kind_of FalseClass, chapter.headers[:another_boolean]
|
49
|
+
end
|
50
|
+
end
|
data/test/test_maneki.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/maneki'
|
3
|
+
|
4
|
+
|
5
|
+
class TestManeki < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@content_path = File.dirname(__FILE__) + '/content'
|
8
|
+
Maneki.path = @content_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_documents_categories
|
12
|
+
assert Maneki.categories.include?('documents')
|
13
|
+
assert_not_equal 0, Maneki.documents.size
|
14
|
+
|
15
|
+
documents = Maneki.documents
|
16
|
+
assert_kind_of Array, documents
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_previous_and_next
|
20
|
+
documents = Maneki.documents
|
21
|
+
first = documents[0]
|
22
|
+
second = documents[1]
|
23
|
+
other_second = Maneki.find 'documents/second-document'
|
24
|
+
third = documents[2]
|
25
|
+
|
26
|
+
assert_not_nil Maneki.previous_before(first)
|
27
|
+
assert_nil Maneki.previous_before(first, :category => 'documents')
|
28
|
+
assert_equal second, Maneki.next_after(first)
|
29
|
+
assert_equal other_second, Maneki.next_after(first)
|
30
|
+
assert_equal third, Maneki.next_after(second)
|
31
|
+
assert_equal third, Maneki.next_after(other_second)
|
32
|
+
assert_nil Maneki.next_after(third)
|
33
|
+
|
34
|
+
assert_equal first, Maneki.next_after(Maneki.previous_before(first))
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maneki
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Nathan Hoad
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-22 00:00:00 +10:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Maneki loads and parses any relevant text files in a given directory
|
22
|
+
email: nathan@nathanhoad.net
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.markdown
|
29
|
+
files:
|
30
|
+
- README.markdown
|
31
|
+
- Rakefile
|
32
|
+
- VERSION
|
33
|
+
- lib/maneki.rb
|
34
|
+
- maneki.gemspec
|
35
|
+
- test/chapter.rb
|
36
|
+
- test/content/chapters/01-the-first-chapter.text
|
37
|
+
- test/content/chapters/02-chapter-2.text
|
38
|
+
- test/content/chapters/03-chapter-with-headers.text
|
39
|
+
- test/content/chapters/04-different-chapter.text
|
40
|
+
- test/content/documents/first-document.text
|
41
|
+
- test/content/documents/second-document.text
|
42
|
+
- test/content/documents/third-document.text
|
43
|
+
- test/test_all.rb
|
44
|
+
- test/test_chapters.rb
|
45
|
+
- test/test_maneki.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://github.com/nathanhoad/maneki
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.3.6
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: A simple file-based model for your Ruby projects
|
76
|
+
test_files:
|
77
|
+
- test/chapter.rb
|
78
|
+
- test/test_all.rb
|
79
|
+
- test/test_chapters.rb
|
80
|
+
- test/test_maneki.rb
|