den 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []