mill 0.1 → 0.3
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.
- checksums.yaml +5 -5
- data/Gemfile +0 -2
- data/TODO.txt +48 -25
- data/bin/mill +19 -0
- data/lib/mill.rb +7 -316
- data/lib/mill/error.rb +7 -0
- data/lib/mill/html_helpers.rb +57 -67
- data/lib/mill/navigator.rb +26 -50
- data/lib/mill/resource.rb +78 -59
- data/lib/mill/resources/dir.rb +31 -0
- data/lib/mill/resources/feed.rb +13 -22
- data/lib/mill/resources/google_site_verification.rb +24 -0
- data/lib/mill/resources/image.rb +12 -5
- data/lib/mill/resources/other.rb +29 -0
- data/lib/mill/resources/redirect.rb +7 -13
- data/lib/mill/resources/robots.rb +6 -9
- data/lib/mill/resources/sitemap.rb +3 -7
- data/lib/mill/resources/stylesheet.rb +27 -0
- data/lib/mill/resources/text.rb +139 -59
- data/lib/mill/site.rb +304 -0
- data/lib/mill/version.rb +2 -2
- data/mill.gemspec +1 -3
- data/test/Gemfile +7 -0
- data/test/Rakefile +7 -0
- data/test/content/a.md +3 -0
- data/test/content/b/index.md +3 -0
- data/test/content/index.md +3 -0
- metadata +24 -37
- data/lib/mill/file_types.rb +0 -30
- data/lib/mill/resources/generic.rb +0 -15
- data/lib/mill/tasks.rake +0 -31
data/lib/mill/site.rb
ADDED
@@ -0,0 +1,304 @@
|
|
1
|
+
module Mill
|
2
|
+
|
3
|
+
class Site
|
4
|
+
|
5
|
+
attr_accessor :input_dir
|
6
|
+
attr_accessor :output_dir
|
7
|
+
attr_accessor :site_title
|
8
|
+
attr_accessor :site_uri
|
9
|
+
attr_accessor :site_email
|
10
|
+
attr_accessor :site_control_date
|
11
|
+
attr_accessor :html_version
|
12
|
+
attr_accessor :feed_resource
|
13
|
+
attr_accessor :sitemap_resource
|
14
|
+
attr_accessor :robots_resource
|
15
|
+
attr_accessor :shorten_uris
|
16
|
+
attr_accessor :make_feed
|
17
|
+
attr_accessor :make_sitemap
|
18
|
+
attr_accessor :make_robots
|
19
|
+
attr_accessor :allow_robots
|
20
|
+
attr_accessor :htpasswd_file
|
21
|
+
attr_accessor :navigator
|
22
|
+
attr_accessor :resource_classes
|
23
|
+
attr_accessor :redirects
|
24
|
+
attr_accessor :resources
|
25
|
+
|
26
|
+
DefaultResourceClasses = ObjectSpace.each_object(Class).select { |c| c < Resource }
|
27
|
+
|
28
|
+
def initialize(input_dir: 'content',
|
29
|
+
output_dir: 'public_html',
|
30
|
+
site_title: nil,
|
31
|
+
site_uri: 'http://localhost',
|
32
|
+
site_email: nil,
|
33
|
+
site_control_date: Date.today.to_s,
|
34
|
+
html_version: :html4_transitional,
|
35
|
+
shorten_uris: true,
|
36
|
+
make_feed: true,
|
37
|
+
make_sitemap: true,
|
38
|
+
make_robots: true,
|
39
|
+
allow_robots: true,
|
40
|
+
htpasswd_file: nil,
|
41
|
+
navigator: nil,
|
42
|
+
google_site_verification: nil,
|
43
|
+
resource_classes: [],
|
44
|
+
redirects: {})
|
45
|
+
|
46
|
+
@input_dir = Path.new(input_dir)
|
47
|
+
@output_dir = Path.new(output_dir)
|
48
|
+
@site_title = site_title
|
49
|
+
@site_uri = Addressable::URI.parse(site_uri)
|
50
|
+
@site_email = Addressable::URI.parse(site_email) if site_email
|
51
|
+
@site_control_date = Date.parse(site_control_date)
|
52
|
+
@html_version = html_version
|
53
|
+
@shorten_uris = shorten_uris
|
54
|
+
@make_feed = make_feed
|
55
|
+
@make_sitemap = make_sitemap
|
56
|
+
@make_robots = make_robots
|
57
|
+
@allow_robots = allow_robots
|
58
|
+
@htpasswd_file = htpasswd_file ? Path.new(htpasswd_file) : nil
|
59
|
+
@resource_classes = resource_classes
|
60
|
+
@navigator = navigator
|
61
|
+
@google_site_verification = google_site_verification
|
62
|
+
@redirects = redirects
|
63
|
+
|
64
|
+
@resources = []
|
65
|
+
@resources_by_uri = {}
|
66
|
+
build_file_types
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_file_types
|
70
|
+
@file_types = {}
|
71
|
+
(DefaultResourceClasses + @resource_classes).each do |resource_class|
|
72
|
+
resource_class.const_get(:FileTypes).each do |type|
|
73
|
+
@file_types[type] = resource_class
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_resource(resource)
|
79
|
+
resource.site = self
|
80
|
+
@resources << resource
|
81
|
+
@resources_by_uri[resource.uri] = resource
|
82
|
+
# ;;warn "added #{resource} as #{resource.uri}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete_resource(resource)
|
86
|
+
@resources.delete(resource)
|
87
|
+
@resources_by_uri.delete(resource.uri)
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_resource(uri)
|
91
|
+
uri = Addressable::URI.parse(uri.to_s) unless uri.kind_of?(Addressable::URI)
|
92
|
+
resource = @resources_by_uri[uri]
|
93
|
+
if resource.nil? && @shorten_uris
|
94
|
+
uri.path = uri.path.sub(%r{\.html$}, '')
|
95
|
+
resource = @resources_by_uri[uri]
|
96
|
+
end
|
97
|
+
resource
|
98
|
+
end
|
99
|
+
|
100
|
+
def resource_for_file(path)
|
101
|
+
find_resource(
|
102
|
+
URI.parse(
|
103
|
+
'/' + URI.encode(
|
104
|
+
path.relative_to(@output_dir).to_s
|
105
|
+
)
|
106
|
+
)
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def home_resource
|
111
|
+
find_resource('/')
|
112
|
+
end
|
113
|
+
|
114
|
+
def tag_uri
|
115
|
+
'tag:%s:' % [
|
116
|
+
[
|
117
|
+
@site_uri.host.downcase,
|
118
|
+
@site_control_date
|
119
|
+
].join(','),
|
120
|
+
]
|
121
|
+
end
|
122
|
+
|
123
|
+
def feed_generator
|
124
|
+
[
|
125
|
+
'Mill',
|
126
|
+
{
|
127
|
+
uri: Addressable::URI.parse('http://github.com/jslabovitz/mill'),
|
128
|
+
version: Mill::VERSION,
|
129
|
+
}
|
130
|
+
]
|
131
|
+
end
|
132
|
+
|
133
|
+
def feed_author_name
|
134
|
+
@site_title
|
135
|
+
end
|
136
|
+
|
137
|
+
def feed_author_uri
|
138
|
+
@site_uri
|
139
|
+
end
|
140
|
+
|
141
|
+
def feed_author_email
|
142
|
+
@site_email
|
143
|
+
end
|
144
|
+
|
145
|
+
def feed_resources
|
146
|
+
public_resources.sort_by(&:date)
|
147
|
+
end
|
148
|
+
|
149
|
+
def public_resources
|
150
|
+
@resources.select(&:public)
|
151
|
+
end
|
152
|
+
|
153
|
+
def private_resources
|
154
|
+
@resources.select { |r| r.kind_of?(Resource::Text) && !r.public }
|
155
|
+
end
|
156
|
+
|
157
|
+
def redirect_resources
|
158
|
+
@resources.select { |r| r.kind_of?(Resource::Redirect) }
|
159
|
+
end
|
160
|
+
|
161
|
+
def make
|
162
|
+
build
|
163
|
+
save
|
164
|
+
end
|
165
|
+
|
166
|
+
def list
|
167
|
+
build
|
168
|
+
on_each_resource do |resource|
|
169
|
+
puts resource.inspect
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def build
|
174
|
+
import_resources
|
175
|
+
load_resources
|
176
|
+
build_resources
|
177
|
+
end
|
178
|
+
|
179
|
+
def import_resources
|
180
|
+
add_files
|
181
|
+
add_redirects
|
182
|
+
add_google_site_verification if @google_site_verification
|
183
|
+
add_feed if @make_feed
|
184
|
+
add_sitemap if @make_sitemap
|
185
|
+
add_robots if @make_robots
|
186
|
+
add_htpasswd if @htpasswd_file
|
187
|
+
end
|
188
|
+
|
189
|
+
def load_resources
|
190
|
+
on_each_resource do |resource|
|
191
|
+
# ;;warn "#{resource.uri}: loading"
|
192
|
+
resource.load
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def build_resources
|
197
|
+
on_each_resource do |resource|
|
198
|
+
# ;;warn "#{resource.uri}: building"
|
199
|
+
resource.build
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def save
|
204
|
+
@output_dir.rmtree if @output_dir.exist?
|
205
|
+
@output_dir.mkpath
|
206
|
+
on_each_resource do |resource|
|
207
|
+
# ;;warn "#{resource.uri}: saving"
|
208
|
+
resource.save
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def on_each_resource(&block)
|
213
|
+
@resources.each do |resource|
|
214
|
+
old_uri = resource.uri.dup
|
215
|
+
begin
|
216
|
+
yield(resource)
|
217
|
+
rescue Error => e
|
218
|
+
raise e, "#{resource.input_file || '-'} (#{old_uri}): #{e}"
|
219
|
+
end
|
220
|
+
if resource.uri != old_uri
|
221
|
+
# ;;warn "URI changed: #{old_uri} => #{resource.uri}"
|
222
|
+
@resources_by_uri.delete(old_uri)
|
223
|
+
@resources_by_uri[resource.uri] = resource
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
private
|
229
|
+
|
230
|
+
def resource_class_for_file(file)
|
231
|
+
MIME::Types.of(file.to_s).each do |type|
|
232
|
+
if (klass = @file_types[type.content_type])
|
233
|
+
return [klass, type]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
nil
|
237
|
+
end
|
238
|
+
|
239
|
+
def add_files
|
240
|
+
raise Error, "Input path not found: #{@input_dir}" unless @input_dir.exist?
|
241
|
+
@input_dir.find do |input_file|
|
242
|
+
if input_file.basename.to_s[0] == '.'
|
243
|
+
Find.prune
|
244
|
+
elsif input_file.directory?
|
245
|
+
# skip
|
246
|
+
elsif (klass, type = resource_class_for_file(input_file))
|
247
|
+
resource = klass.new(
|
248
|
+
input_file: input_file,
|
249
|
+
output_file: @output_dir / input_file.relative_to(@input_dir),
|
250
|
+
type: type)
|
251
|
+
add_resource(resource)
|
252
|
+
else
|
253
|
+
warn "Warning: can't determine resource of file: #{input_file} (#{MIME::Types.of(input_file.to_s).join(', ').inspect})"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def add_feed
|
259
|
+
@feed_resource = Resource::Feed.new(
|
260
|
+
output_file: @output_dir / 'feed.xml')
|
261
|
+
add_resource(@feed_resource)
|
262
|
+
end
|
263
|
+
|
264
|
+
def add_sitemap
|
265
|
+
@sitemap_resource = Resource::Sitemap.new(
|
266
|
+
output_file: @output_dir / 'sitemap.xml')
|
267
|
+
add_resource(@sitemap_resource)
|
268
|
+
end
|
269
|
+
|
270
|
+
def add_robots
|
271
|
+
@robots_resource = Resource::Robots.new(
|
272
|
+
output_file: @output_dir / 'robots.txt')
|
273
|
+
add_resource(@robots_resource)
|
274
|
+
end
|
275
|
+
|
276
|
+
def add_redirects
|
277
|
+
if @redirects
|
278
|
+
@redirects.each do |from, to|
|
279
|
+
output_file = @output_dir / Path.new(from).relative_to('/')
|
280
|
+
resource = Resource::Redirect.new(
|
281
|
+
output_file: output_file,
|
282
|
+
redirect_uri: to)
|
283
|
+
add_resource(resource)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def add_google_site_verification
|
289
|
+
resource = Resource::GoogleSiteVerification.new(
|
290
|
+
output_file: (@output_dir / @google_site_verification).add_extension('.html'),
|
291
|
+
key: @google_site_verification)
|
292
|
+
add_resource(resource)
|
293
|
+
end
|
294
|
+
|
295
|
+
def add_htpasswd
|
296
|
+
resource = Resource::Other.new(
|
297
|
+
input_file: @htpasswd_file,
|
298
|
+
output_file: @output_dir / '.htpasswd')
|
299
|
+
add_resource(resource)
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|
data/lib/mill/version.rb
CHANGED
data/mill.gemspec
CHANGED
@@ -28,9 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_dependency 'path'
|
29
29
|
s.add_dependency 'RedCloth'
|
30
30
|
s.add_dependency 'rubypants'
|
31
|
-
s.add_dependency '
|
32
|
-
s.add_dependency 'term-ansicolor'
|
33
|
-
s.add_dependency 'tidy_ffi'
|
31
|
+
s.add_dependency 'sass'
|
34
32
|
|
35
33
|
s.add_development_dependency 'bundler'
|
36
34
|
s.add_development_dependency 'rake'
|
data/test/Gemfile
ADDED
data/test/Rakefile
ADDED
data/test/content/a.md
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Labovitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -123,35 +123,7 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :runtime
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: term-ansicolor
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :runtime
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: tidy_ffi
|
126
|
+
name: sass
|
155
127
|
requirement: !ruby/object:Gem::Requirement
|
156
128
|
requirements:
|
157
129
|
- - ">="
|
@@ -194,7 +166,8 @@ dependencies:
|
|
194
166
|
version: '0'
|
195
167
|
description: "\n Mill provides a simple but useful static site generator.\n "
|
196
168
|
email: johnl@johnlabovitz.com
|
197
|
-
executables:
|
169
|
+
executables:
|
170
|
+
- mill
|
198
171
|
extensions: []
|
199
172
|
extra_rdoc_files: []
|
200
173
|
files:
|
@@ -204,23 +177,32 @@ files:
|
|
204
177
|
- README.md
|
205
178
|
- Rakefile
|
206
179
|
- TODO.txt
|
180
|
+
- bin/mill
|
207
181
|
- lib/mill.rb
|
208
|
-
- lib/mill/
|
182
|
+
- lib/mill/error.rb
|
209
183
|
- lib/mill/html_helpers.rb
|
210
184
|
- lib/mill/navigator.rb
|
211
185
|
- lib/mill/resource.rb
|
186
|
+
- lib/mill/resources/dir.rb
|
212
187
|
- lib/mill/resources/feed.rb
|
213
|
-
- lib/mill/resources/
|
188
|
+
- lib/mill/resources/google_site_verification.rb
|
214
189
|
- lib/mill/resources/image.rb
|
190
|
+
- lib/mill/resources/other.rb
|
215
191
|
- lib/mill/resources/redirect.rb
|
216
192
|
- lib/mill/resources/robots.rb
|
217
193
|
- lib/mill/resources/sitemap.rb
|
194
|
+
- lib/mill/resources/stylesheet.rb
|
218
195
|
- lib/mill/resources/text.rb
|
219
196
|
- lib/mill/schemas/atom.xsd
|
220
197
|
- lib/mill/schemas/sitemap.xsd
|
221
|
-
- lib/mill/
|
198
|
+
- lib/mill/site.rb
|
222
199
|
- lib/mill/version.rb
|
223
200
|
- mill.gemspec
|
201
|
+
- test/Gemfile
|
202
|
+
- test/Rakefile
|
203
|
+
- test/content/a.md
|
204
|
+
- test/content/b/index.md
|
205
|
+
- test/content/index.md
|
224
206
|
homepage: http://github.com/jslabovitz/mill
|
225
207
|
licenses: []
|
226
208
|
metadata: {}
|
@@ -240,8 +222,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
240
222
|
version: '0'
|
241
223
|
requirements: []
|
242
224
|
rubyforge_project:
|
243
|
-
rubygems_version: 2.
|
225
|
+
rubygems_version: 2.7.3
|
244
226
|
signing_key:
|
245
227
|
specification_version: 4
|
246
228
|
summary: A simple but useful static site generator.
|
247
|
-
test_files:
|
229
|
+
test_files:
|
230
|
+
- test/Gemfile
|
231
|
+
- test/Rakefile
|
232
|
+
- test/content/a.md
|
233
|
+
- test/content/b/index.md
|
234
|
+
- test/content/index.md
|