edison 0.0.1

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.
Files changed (3) hide show
  1. data/README.md +0 -0
  2. data/bin/edison +262 -0
  3. metadata +135 -0
data/README.md ADDED
File without changes
data/bin/edison ADDED
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+ require 'listen'
5
+ require 'kramdown'
6
+ require 'hashie'
7
+ require 'mustache'
8
+ require 'pp'
9
+ require 'webrick'
10
+ require 'yaml'
11
+
12
+ module Edison
13
+ end
14
+
15
+ module Edison::YAMLFrontMatter
16
+ def self.read(fname)
17
+ contents = File.read(fname).strip
18
+ if contents =~ /\A---/
19
+ _, yaml, body = contents.split("---", 3)
20
+ yaml = YAML.load(yaml)
21
+ body ||= ""
22
+ body.strip!
23
+ if yaml.include? "body"
24
+ raise Exception, "YAML Front Matter can't contain a 'body' key. Put it after the front matter."
25
+ end
26
+ {"body" => body}.merge(yaml)
27
+ else
28
+ {"body" => contents}
29
+ end
30
+ end
31
+ end
32
+
33
+ class Edison::ModelsLoader
34
+ def load(directory)
35
+ klasses = Dir[File.join(directory, "*")].map &File.method(:basename)
36
+ hash = Hashie::Mash.new
37
+ klasses.each do |klass|
38
+ objects = Dir[File.join(directory, klass, "*")]
39
+ objects.map! do |fname|
40
+ puts "Loading model #{File.join(klass, File.basename(fname))}..."
41
+
42
+ data = Hashie::Mash.new(case File.extname(fname)
43
+ when /(html)|(md)$/
44
+ Edison::YAMLFrontMatter.read(fname)
45
+ when /ya?ml$/
46
+ YAML.load_file(fname)
47
+ else
48
+ {}
49
+ end)
50
+
51
+ if data._ext
52
+ raise Exception, "Restricted key '_ext' appears in model!"
53
+ end
54
+ data._ext = File.extname(fname)
55
+
56
+ if data._ext == ".md"
57
+ data.body = Kramdown::Document.new(data.body).to_html
58
+ end
59
+
60
+ if data._fname
61
+ raise Exception, "Restricted key '_fname' appears in model!"
62
+ end
63
+ data._fname = File.basename(fname).sub(/#{File.extname(fname)}$/,'')
64
+
65
+ data
66
+ end
67
+ hash[klass] = objects
68
+ end
69
+ hash
70
+ end
71
+ end
72
+
73
+ class Edison::Renderer
74
+ attr_accessor :templates
75
+ def initialize(templates)
76
+ self.templates = templates
77
+ end
78
+ def render(template_name, data)
79
+ template = self.templates[template_name]
80
+ if template.nil?
81
+ raise Exception, "Called for template #{template_name}, but _templates/#{template_name} does not exist"
82
+ end
83
+ body = Mustache.render(template.body, data)
84
+ if template.layout
85
+ newdata = data.merge("yield" => body)
86
+ self.render(template.layout, newdata)
87
+ else
88
+ body
89
+ end
90
+ end
91
+ end
92
+
93
+ class Edison::Router
94
+ attr_reader :urls, :static
95
+ def initialize
96
+ @urls = []
97
+ @static = []
98
+ end
99
+ def url(url, template=nil, data={}, &b)
100
+ if b and template and data
101
+ raise Exception, "Please pass data or block, not both!"
102
+ end
103
+ if b
104
+ b.call(@urls.find { |(url, _, _)| url == url}[2])
105
+ else
106
+ @urls << [url, template, Hashie::Mash.new(data)]
107
+ end
108
+ end
109
+ def copy(url)
110
+ @static << url
111
+ end
112
+ end
113
+
114
+ module Edison
115
+ class <<self
116
+ attr_reader :models, :routes, :renderer
117
+ end
118
+ def self.initialize!(directory)
119
+ @directory = directory
120
+
121
+ @routes = Router.new
122
+
123
+ loader = ModelsLoader.new
124
+ @models = loader.load(File.join(directory, "_models"))
125
+
126
+ templates = Hash[Dir[File.join(directory, "_templates", "*")].map do |fname|
127
+ puts "Loading template _templates/#{File.basename(fname)}..."
128
+ name = File.basename(fname).sub(/\.[^\.]+$/,'')
129
+ data = Hashie::Mash.new Edison::YAMLFrontMatter.read(fname)
130
+ [name, data]
131
+ end]
132
+
133
+ static = Dir[File.join(directory, "**/*")]
134
+ blacklist = ["Gemfile", "Gemfile.lock", "config.rb", "gen.rb", "serve.rb"]
135
+ static.reject! do |fname|
136
+ name = fname.sub(/^#{directory}\//,'')
137
+ dirname = File.dirname(fname)
138
+ blacklist.include?(name) or name =~ /^_/ or File.directory?(fname)
139
+ end
140
+ static.each do |fname|
141
+ name = fname.sub(/^#{directory}\//,'')
142
+ if %w{.html .md}.include?(File.extname(fname))
143
+ data = Hashie::Mash.new Edison::YAMLFrontMatter.read(fname)
144
+ url = name.sub(/\.md$/,'')
145
+ templates[url] = data
146
+ @routes.url url, url, data
147
+ else
148
+ @routes.copy name
149
+ end
150
+ end
151
+
152
+ @renderer = Renderer.new(templates)
153
+ end
154
+ def self.config(&b)
155
+ instance_eval &b
156
+ end
157
+ def self.generate!
158
+ site = File.join(@directory, "_site")
159
+
160
+ FileUtils.rm_rf(site)
161
+ Dir.mkdir(site)
162
+ puts "Copying static files..."
163
+ routes.static.each do |name|
164
+ src = File.join(@directory, name)
165
+ dest = File.join(site, name)
166
+ FileUtils.mkdir_p File.dirname(dest)
167
+ FileUtils.copy src, dest
168
+ end
169
+ routes.urls.each do |(url, template_name, data)|
170
+ puts "Creating /#{url}..."
171
+
172
+ fname = File.join(site, url)
173
+ FileUtils.mkdir_p(File.dirname(fname))
174
+ File.open(fname, "w") do |f|
175
+ f.write @renderer.render(template_name, data)
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ module Edison::Helpers
182
+ def self.date_from_filename(data)
183
+ if data.date
184
+ raise Exception, "Date will be inferred from filename, but found in data"
185
+ end
186
+
187
+ if File.basename(data._fname) =~ /^(\d{4}-\d{1,2}-\d{1,2})/
188
+ data.date = Date.parse($1)
189
+ else
190
+ raise Exception, "Expected filename to start with date (YYYY-M?M-D?D)"
191
+ end
192
+
193
+ data
194
+ end
195
+
196
+ def self.default_layout(data)
197
+ unless data.layout
198
+ data.layout = "default"
199
+ end
200
+
201
+ data
202
+ end
203
+ end
204
+
205
+ def build
206
+ directory = Dir.pwd
207
+ puts "Running in #{directory}..."
208
+ Edison.initialize!(directory)
209
+ load File.join(directory, "config.rb")
210
+ site = File.join(directory, "_site")
211
+ Edison.generate!
212
+ puts "Done!"
213
+ end
214
+
215
+ require 'commander/import'
216
+
217
+ program :name, "Edison"
218
+ program :version, "0.0.1"
219
+ program :description, "Static website generator"
220
+
221
+ default_command :help
222
+
223
+ command :up do |c|
224
+ c.description = "Build static files"
225
+ c.action do |args, options|
226
+ build
227
+ end
228
+ end
229
+ command :serve do |c|
230
+ c.description = "Auto-generating webserver"
231
+ c.action do |args, options|
232
+ directory = Dir.pwd
233
+
234
+ begin
235
+ build
236
+ rescue => e
237
+ pp e
238
+ end
239
+
240
+ listener = Listen.to(directory, :ignore => /^_site\//)
241
+ server = WEBrick::HTTPServer.new(
242
+ :Port => 4000,
243
+ :DocumentRoot => File.expand_path("_site", directory)
244
+ )
245
+ listener.change do |*args|
246
+ t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
247
+ puts "Regenerating at #{t}"
248
+ begin
249
+ build
250
+ rescue => e
251
+ pp e
252
+ end
253
+ end
254
+ listener.start(false)
255
+
256
+ Signal.trap("INT") do
257
+ server.shutdown
258
+ listener.stop
259
+ end
260
+ server.start
261
+ end
262
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: edison
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Michael Maltese
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-03-17 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: commander
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: listen
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: hashie
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: kramdown
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ type: :runtime
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: mustache
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ type: :runtime
89
+ version_requirements: *id005
90
+ description: ""
91
+ email: michael.maltese@pomona.edu
92
+ executables:
93
+ - edison
94
+ extensions: []
95
+
96
+ extra_rdoc_files: []
97
+
98
+ files:
99
+ - bin/edison
100
+ - README.md
101
+ homepage: http://github.com/michaelmaltese/jefe
102
+ licenses: []
103
+
104
+ post_install_message:
105
+ rdoc_options: []
106
+
107
+ require_paths:
108
+ - - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: 3
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.24
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: A static (website) generator.
134
+ test_files: []
135
+