den 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/den ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'den'
6
+ require 'yaml'
7
+
8
+ # If the command was to make a new site, do it and quit
9
+ if "#{ARGV[0]} #{ARGV[1]}".downcase == "new site" and ARGV.length == 3
10
+ Den.create_skeleton(ARGV[2])
11
+ exit
12
+ end
13
+
14
+ # Exit if the '.den' file doesn't exist
15
+ if !File.exists?('.den')
16
+ abort("Make sure you're running from the root of your Den instance.")
17
+ end
18
+
19
+ # Load the config if it exists
20
+ config = YAML::load(File.open('config.yml')) if File.exist?('config.yml')
21
+
22
+ # Create a Den instance
23
+ den = Den.new(config=config)
24
+
25
+ # Process arguments
26
+ case ARGV[0]
27
+
28
+ when 'new'
29
+ # Handle different 'new' cases (page, post)
30
+ if ARGV[1].downcase == 'page'
31
+ if !(ARGV.length == 3 or ARGV.length == 4)
32
+ abort('Invalid format for "new page".')
33
+ end
34
+ den.new_resource('page', :dest => ARGV[2], :file => ARGV[3])
35
+ elsif ARGV[1].downcase == 'post'
36
+ if !(ARGV.length == 2 or ARGV.length == 3)
37
+ abort('Invalid format for "new post".')
38
+ end
39
+ den.new_resource('post', :file => ARGV[2])
40
+ else
41
+ abort("'#{ARGV[1]}' is an invalid argument for 'new'. Must be either 'page' or 'post'.")
42
+ end
43
+
44
+ # Update the site
45
+ den.update_site(refresh=true)
46
+
47
+
48
+ when 'delete'
49
+ abort('Invalid format for command "delete".') if ARGV.length != 3
50
+ if ARGV[1].downcase == 'page' or ARGV[1].downcase == 'post'
51
+ den.delete_resource(ARGV[1].downcase, ARGV[2])
52
+ else
53
+ abort("'#{ARGV[1]}' is an invalid argument for 'delete'. Must be either 'page' or 'post'.")
54
+ end
55
+
56
+ # Update the site
57
+ den.update_site(refresh=true)
58
+
59
+
60
+ when 'list'
61
+ abort('Invalid format for "list".') if ARGV.length > 1
62
+ # Display all the content
63
+ den.print_content
64
+
65
+ # Unrecognized argument, exit
66
+ else
67
+ if ARGV.length > 0
68
+ abort('Invalid command.')
69
+ else
70
+ den.update_site
71
+ end
72
+ end
data/den.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'den'
3
+ s.version = '0.1.0'
4
+ s.summary = 'A really simple static-site generator.'
5
+ s.authors = ["Peter Valdez"]
6
+ s.email = 'peter@someindividual.com'
7
+ s.executables << 'den'
8
+ s.homepage = 'https://github.com/azlyth/den'
9
+ s.files = %w[
10
+ bin/den
11
+ lib/den/examples.rb
12
+ lib/den/page.rb
13
+ lib/den/post.rb
14
+ lib/den/resource.rb
15
+ lib/den/template.rb
16
+ lib/den/utilities.rb
17
+ lib/den.rb
18
+ den.gemspec
19
+ ]
20
+ end
@@ -0,0 +1,25 @@
1
+ # A module used to keep all the skeleton defaults in one place.
2
+ module Examples
3
+ CONFIG = ":site:\n :root: /var/www/\n :posts: musings\n"
4
+
5
+ TEMPLATES = {
6
+ # Base template
7
+ :base => "<html>\n <head>\n <title>{{ title }} | mysite</title>\n </head>\n <body>\n <div id=\"content\">\n {{ body }}\n </div>\n </body>\n</html>\n",
8
+
9
+ # Index template
10
+ :index => "{{ extends base.html }}\n\n{{ block title }}index{{ endblock }}\n\n{{ block body }}\n[[ body ]]\n{{ endblock }}\n",
11
+
12
+ # Page template
13
+ :page => "{{ extends base.html }}\n\n{{ block title }}[[ title ]]{{ endblock }}\n\n{{ block body }}\n[[ content ]]\n{{ endblock }}\n",
14
+
15
+ # Post template
16
+ :post => "{{ extends base.html }}\n\n{{ block title }}[[ title ]]{{ endblock }}\n\n{{ block body }}\n[[ content ]]\n{{ endblock }}\n",
17
+ }
18
+
19
+ # Example page
20
+ PAGE = "[About me]\n\nThis is a test \"about me\" page.\nAsdfasdf.\n\n# Intro\n\n## Past\n\nBlah blah, I did this and that.\n\n## Now\n\nWoah, you do WHAT these days?\n"
21
+
22
+ # Example post
23
+ POST = "[What a post.]\n\nNo, but really, what a post. I'm kidding this is an example post.\nIt's a post that makes a world of a difference.\n\n# Some great point\n\n## A worthy subpoint\n\nAnd some info.\n\nAnd conclude.\n"
24
+
25
+ end
data/lib/den/page.rb ADDED
@@ -0,0 +1,41 @@
1
+ require "cgi"
2
+ require "den/resource"
3
+
4
+ class Page < Resource
5
+
6
+ def to_s
7
+ "Page: #{@content[:id]}"
8
+ end
9
+
10
+
11
+ # Return the HTML rendering of this page
12
+ def html()
13
+ _html = "<div id=\"page\">\n"
14
+
15
+ # Wrap title in anchor if link is provided
16
+ _html += "<h1 id=\"title\">#{@content[:title]}</h1>\n"
17
+
18
+ # Add the rest of the necessary content
19
+ _html += "<div id=\"body\">\n" +
20
+ "#{@content[:body]}\n" +
21
+ "</div>" +
22
+ "</div>"
23
+
24
+ _html
25
+ end
26
+
27
+
28
+ # Pull out metadata and markup the page
29
+ def process
30
+ File.open(@file) do |f|
31
+ page = markup(f.read)
32
+ end
33
+
34
+ # Extract the url from the filename
35
+ page[:id] = @file.split('/')[-1]
36
+
37
+ # Store the processed info
38
+ @content = page
39
+ end
40
+
41
+ end
data/lib/den/post.rb ADDED
@@ -0,0 +1,62 @@
1
+ require "date"
2
+ require "cgi"
3
+ require "den/resource"
4
+
5
+ class Post < Resource
6
+
7
+ def to_s
8
+ "Post #{@content[:id]}"
9
+ end
10
+
11
+
12
+ def [](index)
13
+ @content[index]
14
+ end
15
+
16
+
17
+ # Return the HTML rendering of the post
18
+ def html(link="")
19
+ _html = "<div id=\"post\">\n"
20
+
21
+ # Wrap title in anchor if link is provided
22
+ _html += "<h1 id=\"title\">"
23
+ if link != ""
24
+ _html += "<a href=\"#{link}\">"
25
+ end
26
+ _html += "#{@content[:title]}"
27
+ if link != ""
28
+ _html += "</a>"
29
+ end
30
+
31
+ _html += "</h1>\n"
32
+
33
+
34
+ # Add the rest of the necessary content
35
+ _html += "<h2 id=\"date\">#{@content[:date].strftime("%B %e, %Y")}</h2>\n" +
36
+ "<div id=\"body\">\n" +
37
+ "#{@content[:body]}\n" +
38
+ "</div>\n" +
39
+ "</div>"
40
+
41
+ _html
42
+ end
43
+
44
+
45
+ # Pull out metadata and markup the post
46
+ def process
47
+ File.open(@file) do |f|
48
+ # Extract the date
49
+ post = {
50
+ :id => f.readline.chomp,
51
+ :date => DateTime.strptime(f.readline.chomp, "%Y-%m-%d %H:%M:%S %z")
52
+ }
53
+
54
+ # Process the post
55
+ post.merge!(markup(f.read))
56
+
57
+ # Store the processed info
58
+ @content = post
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,58 @@
1
+ # General Den resource object (included by Page and Post)
2
+ class Resource
3
+
4
+ # Initialize the object
5
+ def initialize(file)
6
+ @file = file
7
+ process
8
+ end
9
+
10
+
11
+ def [](index)
12
+ @content[index]
13
+ end
14
+
15
+
16
+ # Deletes itself
17
+ def delete
18
+ File.delete(@file)
19
+ end
20
+
21
+
22
+ # General markup function
23
+ def markup(s)
24
+ s = CGI::escapeHTML(s)
25
+ title = nil
26
+
27
+ # Extract title
28
+ s.gsub!(/\A\[(.*\S)\]$/) do |x|
29
+ title = $1
30
+ ""
31
+ end
32
+
33
+ # Remove duplicate newlines
34
+ s.gsub!(/\n\n+/, "\n\n")
35
+
36
+ # Remove leading whitespace from lines
37
+ s.gsub!(/^ +/, "")
38
+
39
+ # Pad string to remove edge cases
40
+ s.gsub!(/(\A\n*)|(\n*\z)/, "\n")
41
+
42
+ # Headers
43
+ s.gsub!(/^(#+)\s*(.*)/) {
44
+ len = $1.length
45
+ "<h#{len+1} class=\"header\">#$2</h#{len}>"
46
+ }
47
+
48
+ # Paragraphs
49
+ s.gsub!(/(\A|\n)\n([^<])/, "\n\n<p>\\2")
50
+ s.gsub!(/([^>])\n\n/, "\\1</p>\n\n")
51
+
52
+ # Remove extra newlines
53
+ s.gsub!(/\n+/, "\n")
54
+
55
+ {:title => title, :body => s}
56
+ end
57
+
58
+ end
@@ -0,0 +1,101 @@
1
+ class Template
2
+
3
+ def initialize(template_dir, template_file=nil, post_location=nil)
4
+ @template_dir = template_dir
5
+ load_template(template_file) if !template_file.nil?
6
+ @post_location = post_location
7
+ end
8
+
9
+
10
+ # Calls the appropriate render function
11
+ def render(obj, prev_page=nil, next_page=nil)
12
+ case obj
13
+ when Resource
14
+ return render_resource(obj)
15
+ when Array
16
+ return render_index(obj, prev_page, next_page)
17
+ end
18
+ end
19
+
20
+
21
+ # Returns the HTML of a Resource
22
+ def render_resource(r)
23
+ data = {
24
+ "title" => r[:title],
25
+ "content" => r.html
26
+ }
27
+
28
+ populate(data)
29
+ end
30
+
31
+
32
+ # Returns the HTML of an index
33
+ def render_index(posts, prev_page, next_page)
34
+ # Get the HTML of each Post and combine them
35
+ posts.collect! { |p| p.html(File.join('/', @post_location, p[:id].to_s)) }
36
+ data = { "body" => posts.join("\n\n") }
37
+
38
+ # Append next/previous links if necessary
39
+ if !prev_page.nil?
40
+ data["body"] += "<a class=\"nav\" id=\"future\" href=\"#{prev_page}\">Newer Posts</a>\n"
41
+ end
42
+
43
+ if !next_page.nil?
44
+ data["body"] += "<a class=\"nav\" id=\"past\" href=\"#{next_page}\">Older Posts</a>\n"
45
+ end
46
+
47
+ # Return the rendered index
48
+ populate(data)
49
+ end
50
+
51
+
52
+ # Fills in the template with the data provided
53
+ def populate(data)
54
+ @content.gsub(/\[\[ (\S*) \]\]/) { |x| data[$1] }
55
+ end
56
+
57
+
58
+ # Loads the template file into @content
59
+ def load_template(filename)
60
+ template_path = File.join(@template_dir, filename)
61
+
62
+ if File.file?(template_path)
63
+ # Load the template file
64
+ template_file = ''
65
+ File.open(template_path) do |f|
66
+ template_file = f.read
67
+ end
68
+
69
+ # Check if this template is an extension
70
+ if template_file =~ /{{ extends (\S*) }}/
71
+ # Load the parent template into content
72
+ load_template($1)
73
+
74
+ # Find blocks
75
+ template_file = template_file.split("{{ endblock }}")
76
+ blocks = {}
77
+ for block in template_file
78
+ if /{{ block (?<label>\S*) }}(?<content>[\s\S]*)/ =~ block
79
+ blocks[label] = content
80
+ end
81
+ end
82
+
83
+ # Combine the parent template with the blocks
84
+ merge_templates(blocks)
85
+ else
86
+ # Load the file into content
87
+ @content = template_file
88
+ end
89
+ else
90
+ puts "Unable to locate template: #{@template_dir + filename}."
91
+ end
92
+ end
93
+
94
+ # Combine a template with its parent
95
+ def merge_templates(blocks)
96
+ @content.gsub!(/{{ (\S*) }}/) do |x|
97
+ blocks[$1]
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,19 @@
1
+ # Given a filename (and extension, optionally), returns an unused filename.
2
+ def get_unused_filename(filename, extension="")
3
+ extension = "." + extension if extension != ""
4
+
5
+ full_path = filename + extension
6
+
7
+ if File.exists?(full_path)
8
+ count = 1
9
+
10
+ # Keep adding to the count until we find filename that isn't taken.
11
+ while File.exists?("#{filename}_#{count}#{extension}")
12
+ count += 1
13
+ end
14
+
15
+ full_path = "#{filename}_#{count}#{extension}"
16
+ end
17
+
18
+ full_path
19
+ end
data/lib/den.rb ADDED
@@ -0,0 +1,322 @@
1
+ require "fileutils"
2
+ require "date"
3
+ require "den/post"
4
+ require "den/page"
5
+ require "den/template"
6
+ require "den/utilities"
7
+ require "den/examples"
8
+
9
+ class Den
10
+
11
+ # Creates a new Den site
12
+ def self.create_skeleton(location)
13
+ # Create the directories along with default templates
14
+ Dir.mkdir(location)
15
+ Dir.mkdir(File.join(location, 'pages'))
16
+ Dir.mkdir(File.join(location, 'posts'))
17
+ Dir.mkdir(File.join(location, 'posts', 'new'))
18
+ Dir.mkdir(File.join(location, 'templates'))
19
+ Examples::TEMPLATES.each_pair { |file, content|
20
+ File.open(File.join(location, 'templates', file.to_s + '.html'), 'w') do |f|
21
+ f.print(content)
22
+ end
23
+ }
24
+
25
+ File.open(File.join(location, 'config.yml'), 'w') do |f|
26
+ f.write(Examples::CONFIG)
27
+ end
28
+
29
+ # Create the file that indicates this is a Den instance
30
+ FileUtils.touch(File.join(location, '.den'))
31
+
32
+ puts "Created new site in '#{location}'."
33
+ end
34
+
35
+ # Default configuration values
36
+ @@default_config = {
37
+ # Where pages are actually served from
38
+ # Note the following:
39
+ # - 'root' gets prepended to all locations but 'index'
40
+ # - 'posts' gets prepended to 'index'
41
+ :site => {
42
+ :root => "/var/www/",
43
+ :pages => "",
44
+ :posts => "posts/",
45
+ :index => "index/",
46
+ },
47
+ }
48
+
49
+ @@default_meta = {
50
+ # The number of total posts
51
+ :last_post => 0,
52
+ }
53
+
54
+
55
+ # Create the Den and store the config, prioritizing the provided one.
56
+ def initialize(config=nil)
57
+ @config = @@default_config
58
+
59
+ if !config.nil?
60
+ @config[:new_posts] = config[:new_posts] if !config[:new_posts].nil?
61
+ @config[:site].merge!(config[:site]) if !config[:site].nil?
62
+ end
63
+
64
+ load_metadata
65
+ gather_new_posts
66
+ prepare_content
67
+ end
68
+
69
+
70
+
71
+
72
+ # Update the site
73
+ def update_site(refresh=false)
74
+ if refresh
75
+ prepare_content
76
+ end
77
+ push_content
78
+ create_indices
79
+ puts "Updated the site."
80
+ end
81
+
82
+
83
+ # Display the Den's pages and posts, along with their metadata
84
+ def print_content
85
+ puts "Pages:" if !@pages.empty?
86
+ @pages.each do |p|
87
+ puts " #{p[:id]} (title: '#{p[:title]}')"
88
+ end
89
+
90
+ puts "Posts:" if !@posts.empty?
91
+ @posts.each do |p|
92
+ puts " #{p[:id]} (title: '#{p[:title]}', date: #{p[:date].strftime("%B %e, %Y")})"
93
+ end
94
+
95
+ if @pages.empty? and @posts.empty?
96
+ puts "No content."
97
+ end
98
+ end
99
+
100
+
101
+ # Adds a page or post. If a file is provided, it copies the contents of the
102
+ # file. Otherwise, it will start the default editor to make the new resource.
103
+ def new_resource(type, options)
104
+ defaults = {:file => nil, :dest => nil}
105
+ options = defaults.merge(options)
106
+ type.downcase!
107
+
108
+ if options[:file].nil?
109
+ # Create the new page/post with the default editor
110
+ if type == 'page'
111
+ file = File.join('pages', options[:dest])
112
+ system("/usr/bin/editor #{file}")
113
+ elsif type == 'post'
114
+ file = File.join('posts', 'new', 'new.post')
115
+ system("/usr/bin/editor #{file}")
116
+ gather_new_posts
117
+ end
118
+
119
+ if File.exists?(file)
120
+ puts "Added a #{type}."
121
+ else
122
+ puts "Cancelled adding a #{type}."
123
+ end
124
+
125
+ else
126
+ # Copy the file that will be the new page/post
127
+ if type == 'page'
128
+ FileUtils.cp(options[:file], File.join('pages', options[:dest]))
129
+ elsif type == 'post'
130
+ FileUtils.cp(options[:file], File.join('posts', 'new'))
131
+ gather_new_posts
132
+ end
133
+
134
+ puts "Using #{options[:file]} as a new #{type}."
135
+ end
136
+ end
137
+
138
+
139
+ # Deletes a page/post, identified by its ID
140
+ def delete_resource(type, id)
141
+ type.downcase!
142
+
143
+ # Find the page/post
144
+ if type == 'page'
145
+ res = @pages.select { |p| p[:id] == id }
146
+ fn = File.join(@config[:site][:root], @config[:site][:pages])
147
+ elsif type == 'post'
148
+ res = @posts.select { |p| p[:id] == id }
149
+ fn = File.join(@config[:site][:root], @config[:site][:posts])
150
+ end
151
+
152
+ # If we found a resource, delete it.
153
+ if !res.nil?
154
+ res = res[0]
155
+ fn = File.join(fn, res[:id])
156
+ File.delete(fn) if File.exists?(fn)
157
+ res.delete
158
+ puts "Deleted #{type} '#{id}'."
159
+ else
160
+ puts "No #{type} with id '#{id}'."
161
+ end
162
+ end
163
+
164
+
165
+ def load_metadata
166
+ @meta = @@default_meta
167
+
168
+ meta_file = File.join("metadata.yml")
169
+
170
+ # Load the metadata
171
+ if File.exists?(meta_file)
172
+ yml = YAML::load(File.open(meta_file))
173
+ @meta.merge!(yml)
174
+ end
175
+ end
176
+
177
+
178
+ def save_metadata
179
+ meta_file = File.join("metadata.yml")
180
+
181
+ File.open(meta_file, 'w') do |f|
182
+ f.puts("# Do not touch this file, as it's auto-generated.")
183
+ YAML::dump(@meta, f)
184
+ end
185
+ end
186
+
187
+
188
+ # Create the indices for the posts
189
+ def create_indices
190
+ destination = File.join(@config[:site][:root], @config[:site][:posts], @config[:site][:index])
191
+ Dir.mkdir(destination) if !Dir.exists?(destination)
192
+
193
+ # Clear out the indices before making them
194
+ Dir.entries(destination).each do |f|
195
+ index = File.join(destination, f)
196
+ File.delete(index) if File.file?(index)
197
+ end
198
+
199
+ temp_dir = File.join("templates")
200
+ template = Template.new(temp_dir, 'index.html', post_location=@config[:site][:posts])
201
+ indices = []
202
+
203
+ # Segment the posts into groups of 5
204
+ @posts.each_slice(5) { |posts|
205
+ indices << posts
206
+ }
207
+
208
+ # Create the indices and save them
209
+ indices.length.times { |i|
210
+ p_pg = nil
211
+ n_pg = nil
212
+
213
+ # Find the relative location (to the site) of the index
214
+ rel_index = File.join("/", @config[:site][:posts], @config[:site][:index])
215
+
216
+ # Figure out the previous/next pages, if they exist
217
+ p_pg = File.join(rel_index, i.to_s) if i > 0
218
+ n_pg = File.join(rel_index, (i+2).to_s) if i + 1 < indices.length
219
+
220
+ # Render the index page
221
+ indices[i] = template.render(indices[i], prev_page=p_pg, next_page=n_pg)
222
+
223
+ # Save the index page
224
+ index_file = File.join(destination, (i+1).to_s)
225
+ File.open(index_file, 'w') do |f|
226
+ f.print(indices[i])
227
+ end
228
+ }
229
+ end
230
+
231
+
232
+ # Publish the posts and pages
233
+ def push_content
234
+ temp_dir = File.join("templates")
235
+
236
+ # Create the post directory if it doesn't exist
237
+ destination = File.join(@config[:site][:root], @config[:site][:posts])
238
+ Dir.mkdir(destination) if !Dir.exists?(destination)
239
+
240
+ # Render and save each post to the post directory
241
+ template = Template.new(temp_dir, 'post.html')
242
+ @posts.each do |post|
243
+ post_file = File.join(destination, post[:id])
244
+ File.open(post_file, 'w') do |f|
245
+ f.print(template.render(post))
246
+ end
247
+ end
248
+
249
+ # Create the page directory if it doesn't exist
250
+ destination = File.join(@config[:site][:root], @config[:site][:pages])
251
+ Dir.mkdir(destination) if !Dir.exists?(destination)
252
+
253
+ # Render and save each page to the page directory
254
+ template = Template.new(temp_dir, 'page.html')
255
+ @pages.each do |page|
256
+ page_file = File.join(destination, page[:id])
257
+ File.open(page_file, 'w') do |f|
258
+ f.print(template.render(page))
259
+ end
260
+ end
261
+
262
+ end
263
+
264
+ # Move any new posts to the saved posts directory.
265
+ def gather_new_posts
266
+ new_dir = File.join("posts", "new")
267
+
268
+ Dir.entries(new_dir).each do |f|
269
+ post_file = File.join(new_dir, f)
270
+ if File.file?(post_file)
271
+
272
+ # Save the new post to the processed directory with metadata attached
273
+ File.open(post_file) do |new_post|
274
+ date = new_post.mtime
275
+ save_path = get_unused_filename(File.join("posts", date.strftime("%Y-%m-%d")), "post")
276
+
277
+ File.open(save_path, "w") do |save_file|
278
+ save_file.puts(@meta[:last_post] + 1)
279
+ save_file.puts(date.strftime("%Y-%m-%d %H:%M:%S %z"))
280
+ save_file.print(new_post.read)
281
+ end
282
+ end
283
+
284
+ # Remove the file from the new post directory
285
+ File.delete(post_file)
286
+
287
+ # Update the value of the last ID used
288
+ @meta[:last_post] += 1
289
+
290
+ end
291
+ end
292
+ end
293
+
294
+ # Process the pages and posts
295
+ def prepare_content
296
+ @posts = []
297
+ @pages = []
298
+
299
+ # Create a Post for each file in the posts directory
300
+ Dir.entries('posts').each do |f|
301
+ entry = File.join('posts', f)
302
+ if File.file?(entry)
303
+ @posts << Post.new(entry)
304
+ end
305
+ end
306
+
307
+ # Create a Page for each file in the pages directory
308
+ Dir.entries('pages').each do |f|
309
+ entry = File.join('pages', f)
310
+ if File.file?(entry)
311
+ @pages << Page.new(entry)
312
+ end
313
+ end
314
+
315
+ save_metadata
316
+
317
+ # Sort the posts by date, with most recent first
318
+ @posts.sort_by! { |post| post[:date] }
319
+ @posts.reverse!
320
+ end
321
+
322
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: den
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Peter Valdez
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-25 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email: peter@someindividual.com
16
+ executables:
17
+ - den
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/den
22
+ - lib/den/examples.rb
23
+ - lib/den/page.rb
24
+ - lib/den/post.rb
25
+ - lib/den/resource.rb
26
+ - lib/den/template.rb
27
+ - lib/den/utilities.rb
28
+ - lib/den.rb
29
+ - den.gemspec
30
+ homepage: https://github.com/azlyth/den
31
+ licenses: []
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 1.8.11
51
+ signing_key:
52
+ specification_version: 3
53
+ summary: A really simple static-site generator.
54
+ test_files: []