henshin 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/README.markdown +0 -1
- data/Rakefile +4 -1
- data/VERSION +1 -1
- data/bin/files.rb +46 -0
- data/bin/henshin +47 -79
- data/henshin.gemspec +37 -14
- data/lib/henshin.rb +50 -36
- data/lib/henshin/archive.rb +161 -0
- data/lib/henshin/categories.rb +6 -1
- data/lib/henshin/ext.rb +2 -53
- data/lib/henshin/gen.rb +16 -15
- data/lib/henshin/plugin.rb +20 -7
- data/lib/henshin/plugins/highlight.rb +31 -0
- data/lib/henshin/plugins/liquid.rb +48 -14
- data/lib/henshin/plugins/maruku.rb +3 -4
- data/lib/henshin/plugins/sass.rb +7 -6
- data/lib/henshin/plugins/textile.rb +3 -4
- data/lib/henshin/post.rb +50 -8
- data/lib/henshin/site.rb +60 -34
- data/lib/henshin/tags.rb +5 -1
- data/test/site/css/{print.sass → includes/reset.sass} +0 -3
- data/test/site/css/{screen.css → print.css} +1 -4
- data/test/site/css/screen.sass +70 -0
- data/test/site/includes/head.html +1 -0
- data/test/site/index.html +12 -2
- data/test/site/layouts/archive_date.html +19 -0
- data/test/site/layouts/archive_month.html +19 -0
- data/test/site/layouts/archive_year.html +19 -0
- data/test/site/layouts/category_index.html +5 -4
- data/test/site/layouts/category_page.html +2 -2
- data/test/site/layouts/main.html +1 -36
- data/test/site/layouts/post.html +15 -5
- data/test/site/layouts/tag_index.html +3 -3
- data/test/site/layouts/tag_page.html +2 -2
- data/test/site/options.yaml +7 -4
- data/test/site/posts/Testing-Stuff.markdown +7 -1
- data/test/test_archives.rb +27 -0
- data/test/test_categories.rb +0 -0
- data/test/test_gens.rb +28 -7
- data/test/test_options.rb +4 -2
- data/test/test_posts.rb +50 -14
- data/test/test_site.rb +55 -7
- data/test/test_statics.rb +0 -0
- data/test/test_tags.rb +0 -0
- data/test/text_exts.rb +0 -0
- metadata +86 -17
- data/lib/henshin/plugins/pygments.rb +0 -17
@@ -3,14 +3,13 @@ require 'maruku'
|
|
3
3
|
|
4
4
|
class MarukuPlugin < Henshin::Generator
|
5
5
|
|
6
|
-
attr_accessor :extensions, :config
|
7
|
-
|
8
|
-
Defaults = {}
|
6
|
+
attr_accessor :extensions, :config, :priority
|
9
7
|
|
10
8
|
def initialize( override={} )
|
11
9
|
@extensions = {:input => ['markdown', 'mkdwn', 'md'],
|
12
10
|
:output => 'html'}
|
13
|
-
@config =
|
11
|
+
@config = {}
|
12
|
+
@priority = 5
|
14
13
|
end
|
15
14
|
|
16
15
|
def generate( content )
|
data/lib/henshin/plugins/sass.rb
CHANGED
@@ -3,7 +3,7 @@ require 'sass'
|
|
3
3
|
|
4
4
|
class SassPlugin < Henshin::Generator
|
5
5
|
|
6
|
-
attr_accessor :extensions, :config, :
|
6
|
+
attr_accessor :extensions, :config, :priority
|
7
7
|
|
8
8
|
Defaults = {:ignore_layouts => true,
|
9
9
|
:style => :nested}
|
@@ -11,17 +11,18 @@ class SassPlugin < Henshin::Generator
|
|
11
11
|
def initialize
|
12
12
|
@extensions = {:input => ['sass', 'scss'],
|
13
13
|
:output => 'css'}
|
14
|
-
@
|
14
|
+
@config = {:ignore_layouts => true,
|
15
|
+
:style => :nested}
|
16
|
+
@priority = 5
|
15
17
|
end
|
16
18
|
|
17
19
|
def configure( override )
|
18
|
-
|
20
|
+
@config.merge!(override) if override
|
19
21
|
end
|
20
22
|
|
21
23
|
def generate( content )
|
22
|
-
|
23
|
-
output = engine.render
|
24
|
+
Sass::Engine.new(content, @config).render
|
24
25
|
end
|
25
26
|
|
26
|
-
Henshin.register! self
|
27
|
+
Henshin.register! self, :sass
|
27
28
|
end
|
@@ -3,14 +3,13 @@ require 'redcloth'
|
|
3
3
|
|
4
4
|
class TextilePlugin < Henshin::Generator
|
5
5
|
|
6
|
-
attr_accessor :extensions, :config
|
7
|
-
|
8
|
-
Defaults = {}
|
6
|
+
attr_accessor :extensions, :config, :priority
|
9
7
|
|
10
8
|
def initialize( override={} )
|
11
9
|
@extensions = {:input => ['textile'],
|
12
10
|
:output => 'html'}
|
13
|
-
@config =
|
11
|
+
@config = {}
|
12
|
+
@priority = 5
|
14
13
|
end
|
15
14
|
|
16
15
|
def generate( content )
|
data/lib/henshin/post.rb
CHANGED
@@ -60,9 +60,9 @@ module Henshin
|
|
60
60
|
file_data.each_with_index do |data, i|
|
61
61
|
if data_order[i].include? 'title'
|
62
62
|
if data_order[i].include? 'dashes'
|
63
|
-
override[:title] = data.gsub(/-/, ' ')
|
63
|
+
override[:title] = data.gsub(/-/, ' ')
|
64
64
|
else
|
65
|
-
override[:title] = data
|
65
|
+
override[:title] = data
|
66
66
|
end
|
67
67
|
elsif data_order[i].include? 'date'
|
68
68
|
override[:date] = data
|
@@ -92,7 +92,7 @@ module Henshin
|
|
92
92
|
#
|
93
93
|
# @param [Hash] override data to override settings with
|
94
94
|
def override( override )
|
95
|
-
@title = override[:title]
|
95
|
+
@title = override[:title].titlecase if override[:title]
|
96
96
|
@layout = @site.layouts[ override[:layout] ] if override[:layout]
|
97
97
|
@date = Time.parse( override[:date] ) if override[:date]
|
98
98
|
@tags = override[:tags].split(', ') if override[:tags]
|
@@ -112,17 +112,24 @@ module Henshin
|
|
112
112
|
#
|
113
113
|
# @return [Hash] the payload for the layout engine
|
114
114
|
def payload
|
115
|
-
{
|
115
|
+
r = {
|
116
116
|
'yield' => @content,
|
117
117
|
'site' => @site.payload['site'],
|
118
118
|
'post' => self.to_hash
|
119
119
|
}
|
120
|
+
r['post']['next'] = self.next.to_hash if self.next
|
121
|
+
r['post']['prev'] = self.prev.to_hash if self.prev
|
122
|
+
r
|
120
123
|
end
|
121
124
|
|
122
125
|
# Turns all of the post data into a hash
|
123
126
|
#
|
124
127
|
# @return [Hash]
|
125
128
|
def to_hash
|
129
|
+
tags = []
|
130
|
+
@site.tags.select{ |t| @tags.include?(t) }.each do |k, tag|
|
131
|
+
tags << {'name' => tag.name, 'url' => tag.url}
|
132
|
+
end
|
126
133
|
{
|
127
134
|
'title' => @title,
|
128
135
|
'author' => @author,
|
@@ -130,18 +137,44 @@ module Henshin
|
|
130
137
|
'url' => self.url,
|
131
138
|
'date' => @date,
|
132
139
|
'category' => @category,
|
133
|
-
'tags' =>
|
134
|
-
'content' => @content
|
140
|
+
'tags' => tags,
|
141
|
+
'content' => @content
|
135
142
|
}
|
136
143
|
end
|
144
|
+
|
145
|
+
# Gets the post after this one
|
146
|
+
#
|
147
|
+
# @return [Post] next post
|
148
|
+
def next
|
149
|
+
if i = @site.posts.index(self)
|
150
|
+
if i < @site.posts.size - 1
|
151
|
+
@site.posts[i+1]
|
152
|
+
else
|
153
|
+
nil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Gets the post before this one
|
159
|
+
#
|
160
|
+
# @return [Post] previous post
|
161
|
+
def prev
|
162
|
+
if i = @site.posts.index(self)
|
163
|
+
if i > 0
|
164
|
+
@site.posts[i-1]
|
165
|
+
else
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
137
170
|
|
138
171
|
|
139
172
|
##
|
140
173
|
# Writes the file to the correct place
|
141
174
|
def write
|
142
175
|
write_path = File.join( config[:root], config[:target], permalink )
|
143
|
-
FileUtils.mkdir_p
|
144
|
-
file = File.new(
|
176
|
+
FileUtils.mkdir_p write_path.directory
|
177
|
+
file = File.new( write_path, "w" )
|
145
178
|
file.puts( @content )
|
146
179
|
end
|
147
180
|
|
@@ -158,6 +191,15 @@ module Henshin
|
|
158
191
|
end
|
159
192
|
end
|
160
193
|
|
194
|
+
def <=>(other)
|
195
|
+
s = self.date <=> other.date
|
196
|
+
if s == 0
|
197
|
+
self.permalink <=> other.permalink
|
198
|
+
else
|
199
|
+
s
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
161
203
|
def inspect
|
162
204
|
"#<Post:#{@path}>"
|
163
205
|
end
|
data/lib/henshin/site.rb
CHANGED
@@ -16,7 +16,7 @@ module Henshin
|
|
16
16
|
@gens = []
|
17
17
|
@statics = []
|
18
18
|
|
19
|
-
@archive =
|
19
|
+
@archive = Archive.new( self )
|
20
20
|
@tags = Hash.new { |h, k| h[k] = Tag.new(k) }
|
21
21
|
@categories = Hash.new { |h, k| h[k] = Category.new(k) }
|
22
22
|
|
@@ -40,45 +40,43 @@ module Henshin
|
|
40
40
|
def read
|
41
41
|
self.read_layouts
|
42
42
|
self.read_posts
|
43
|
-
self.
|
43
|
+
self.read_gens
|
44
|
+
self.read_statics
|
44
45
|
end
|
45
46
|
|
46
47
|
# Adds all items in 'layouts' to the layouts array
|
47
48
|
def read_layouts
|
48
|
-
path = File.join(config[:root], 'layouts')
|
49
|
+
path = File.join(@config[:root], 'layouts')
|
49
50
|
Dir.glob(path + '/*.*').each do |layout|
|
50
51
|
layout =~ /([a-zA-Z0-9 _-]+)\.([a-zA-Z0-9-]+)/
|
51
|
-
@layouts[$1] = layout
|
52
|
+
@layouts[$1] = File.open(layout, 'r') {|f| f.read}
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
55
56
|
# Adds all items in 'posts' to the posts array
|
56
57
|
def read_posts
|
57
|
-
path = File.join(config[:root], 'posts')
|
58
|
+
path = File.join(@config[:root], 'posts')
|
58
59
|
Dir.glob(path + '/**/*.*').each do |post|
|
59
60
|
@posts << Post.new(post, self)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
|
-
#
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
['/_site', '/plugins'].each do |r|
|
69
|
-
items = items.select {|i| !i.include?( File.join(config[:root], r) )}
|
70
|
-
end
|
71
|
-
|
72
|
-
gens = items.select {|i| i.gen?(self.config)}
|
64
|
+
# Adds all files that need to be run through a plugin in an array
|
65
|
+
def read_gens
|
66
|
+
files = Dir.glob( File.join(@config[:root], '**', '*.*') )
|
67
|
+
gens = files.select {|i| gen?(i) }
|
73
68
|
gens.each do |g|
|
74
69
|
@gens << Gen.new(g, self)
|
75
70
|
end
|
76
|
-
|
77
|
-
|
71
|
+
end
|
72
|
+
|
73
|
+
# Adds all static files to an array
|
74
|
+
def read_statics
|
75
|
+
files = Dir.glob( File.join(@config[:root], '**', '*.*') )
|
76
|
+
static = files.select {|i| static?(i) }
|
78
77
|
static.each do |s|
|
79
78
|
@statics << Static.new(s, self)
|
80
79
|
end
|
81
|
-
|
82
80
|
end
|
83
81
|
|
84
82
|
|
@@ -103,11 +101,11 @@ module Henshin
|
|
103
101
|
'description' => @config[:description],
|
104
102
|
'time_zone' => @config[:time_zone],
|
105
103
|
'created_at' => Time.now,
|
106
|
-
'posts' => @posts.collect
|
104
|
+
'posts' => @posts.collect{|i| i.to_hash},
|
107
105
|
'tags' => @tags.collect {|k, t| t.to_hash},
|
108
106
|
'categories' => @categories.collect {|k, t| t.to_hash},
|
109
|
-
'archive' => @archive
|
110
|
-
}
|
107
|
+
'archive' => @archive.to_hash
|
108
|
+
}
|
111
109
|
}
|
112
110
|
end
|
113
111
|
|
@@ -129,21 +127,14 @@ module Henshin
|
|
129
127
|
|
130
128
|
# @return [Hash] archive hash
|
131
129
|
def build_archive
|
132
|
-
{
|
133
|
-
'2010' => {
|
134
|
-
'01' => [
|
135
|
-
{'post' => 'hash'},
|
136
|
-
{'post' => 'hash'}
|
137
|
-
]
|
138
|
-
}
|
139
|
-
}
|
130
|
+
@posts.each {|p| @archive.add_post(p)}
|
140
131
|
end
|
141
132
|
|
142
133
|
##
|
143
134
|
# Renders the files
|
144
135
|
def render
|
145
136
|
@posts.each_parallel {|p| p.render}
|
146
|
-
@gens.
|
137
|
+
@gens.each {|g| g.render}
|
147
138
|
end
|
148
139
|
|
149
140
|
|
@@ -154,6 +145,7 @@ module Henshin
|
|
154
145
|
@gens.each_parallel {|g| g.write}
|
155
146
|
@statics.each_parallel {|s| s.write}
|
156
147
|
|
148
|
+
@archive.write
|
157
149
|
self.write_tags
|
158
150
|
self.write_categories
|
159
151
|
end
|
@@ -161,7 +153,7 @@ module Henshin
|
|
161
153
|
# Writes the necessary pages for tags, but only if the correct layouts are present
|
162
154
|
def write_tags
|
163
155
|
if @layouts['tag_index']
|
164
|
-
write_path = File.join( config[:root], 'tags', 'index.html' )
|
156
|
+
write_path = File.join( @config[:root], 'tags', 'index.html' )
|
165
157
|
|
166
158
|
tag_index = Gen.new(write_path, self)
|
167
159
|
tag_index.layout = @layouts['tag_index']
|
@@ -172,7 +164,7 @@ module Henshin
|
|
172
164
|
|
173
165
|
if @layouts['tag_page']
|
174
166
|
@tags.each do |n, tag|
|
175
|
-
write_path = File.join( config[:root], 'tags', tag.name, 'index.html' )
|
167
|
+
write_path = File.join( @config[:root], 'tags', tag.name, 'index.html' )
|
176
168
|
|
177
169
|
payload = {:name => 'tag', :payload => tag.to_hash}
|
178
170
|
tag_page = Gen.new(write_path, self, payload)
|
@@ -187,7 +179,7 @@ module Henshin
|
|
187
179
|
# Writes the necessary pages for categories, but only if the correct layouts are present
|
188
180
|
def write_categories
|
189
181
|
if @layouts['category_index']
|
190
|
-
write_path = File.join( config[:root], 'categories', 'index.html' )
|
182
|
+
write_path = File.join( @config[:root], 'categories', 'index.html' )
|
191
183
|
|
192
184
|
category_index = Gen.new(write_path, self)
|
193
185
|
category_index.layout = @layouts['category_index']
|
@@ -198,7 +190,7 @@ module Henshin
|
|
198
190
|
|
199
191
|
if @layouts['category_page']
|
200
192
|
@categories.each do |n, category|
|
201
|
-
write_path = File.join( config[:root], 'categories', category.name, 'index.html' )
|
193
|
+
write_path = File.join( @config[:root], 'categories', category.name, 'index.html' )
|
202
194
|
|
203
195
|
payload = {:name => 'category', :payload => category.to_hash}
|
204
196
|
category_page = Gen.new(write_path, self, payload)
|
@@ -209,6 +201,40 @@ module Henshin
|
|
209
201
|
end
|
210
202
|
end
|
211
203
|
end
|
204
|
+
|
205
|
+
|
206
|
+
# @return [Bool]
|
207
|
+
def static?( path )
|
208
|
+
!( layout?(path) || post?(path) || gen?(path) || ignored?(path) )
|
209
|
+
end
|
210
|
+
|
211
|
+
# @return [Bool]
|
212
|
+
def layout?( path )
|
213
|
+
path.include?('layouts/') && !ignored?(path)
|
214
|
+
end
|
215
|
+
|
216
|
+
# @return [Bool]
|
217
|
+
def post?( path )
|
218
|
+
path.include?('posts/') && !ignored?(path)
|
219
|
+
end
|
220
|
+
|
221
|
+
# @return [Bool]
|
222
|
+
def gen?( path )
|
223
|
+
return false if post?(path) || layout?(path) || ignored?(path)
|
224
|
+
return true if @config[:plugins][:generators].has_key? path.extension
|
225
|
+
return true if File.open(path, "r").read(3) == "---"
|
226
|
+
false
|
227
|
+
end
|
228
|
+
|
229
|
+
# @return [Bool]
|
230
|
+
def ignored?( path )
|
231
|
+
ignored = ['/options.yaml'] + @config[:exclude]
|
232
|
+
ignored.collect! {|i| File.join(@config[:root], i)}
|
233
|
+
ignored.each do |i|
|
234
|
+
return true if path.include? i
|
235
|
+
end
|
236
|
+
false
|
237
|
+
end
|
212
238
|
|
213
239
|
end
|
214
240
|
end
|
data/lib/henshin/tags.rb
CHANGED
@@ -11,10 +11,14 @@ module Henshin
|
|
11
11
|
def to_hash
|
12
12
|
hash = {
|
13
13
|
'name' => @name,
|
14
|
-
'posts' => @posts.collect {|i| i.to_hash}
|
14
|
+
'posts' => @posts.sort.collect {|i| i.to_hash},
|
15
|
+
'url' => self.url
|
15
16
|
}
|
16
17
|
end
|
17
18
|
|
19
|
+
def url
|
20
|
+
"/tags/#{@name.slugify}/"
|
21
|
+
end
|
18
22
|
|
19
23
|
def inspect
|
20
24
|
"#<Tag:#{@name}>"
|
@@ -1,5 +1,3 @@
|
|
1
|
-
/* Testing whether static files, eg this, are correctly copied and ignored */
|
2
|
-
|
3
1
|
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,
|
4
2
|
blockquote,th,td {margin:0; padding:0; }
|
5
3
|
table { border-collapse:collapse; border-spacing:0; }
|
@@ -9,7 +7,6 @@ ol,ul { list-style:none; }
|
|
9
7
|
caption,th { text-align:left; }
|
10
8
|
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
|
11
9
|
q:before,q:after { content:”; }
|
12
|
-
abbr,acronym { border:0; }
|
13
|
-
html {font-size: 62.5%;}p {font-size: 1.2em;}
|
10
|
+
abbr,acronym { border:0; }html {font-size: 62.5%;}p {font-size: 1.2em;}
|
14
11
|
h1 {font-size: 2em;}
|
15
12
|
a:hover, a:active { outline: none; }
|
@@ -0,0 +1,70 @@
|
|
1
|
+
@import includes/reset.css
|
2
|
+
|
3
|
+
body
|
4
|
+
width: 500px
|
5
|
+
margin: 20px
|
6
|
+
background: rgb(254, 254, 254)
|
7
|
+
line-height: 20px
|
8
|
+
font:
|
9
|
+
family: Helvetica, Arial, sans-serif
|
10
|
+
size: 16px
|
11
|
+
|
12
|
+
h1, h2
|
13
|
+
color: rgb(50, 50, 50)
|
14
|
+
line-height: 32px
|
15
|
+
font:
|
16
|
+
size: 22px
|
17
|
+
weight: bold
|
18
|
+
|
19
|
+
h2
|
20
|
+
font-size: 18px
|
21
|
+
|
22
|
+
p, ul, ol, pre
|
23
|
+
margin: 16px 0
|
24
|
+
|
25
|
+
a
|
26
|
+
color: rgb(20, 20, 180)
|
27
|
+
|
28
|
+
b, strong
|
29
|
+
font-weight: bold
|
30
|
+
|
31
|
+
i, em
|
32
|
+
font-style: italic
|
33
|
+
|
34
|
+
pre
|
35
|
+
background: rgb(240, 240, 245)
|
36
|
+
border: 1px solid rgb(200, 200, 202)
|
37
|
+
|
38
|
+
code
|
39
|
+
line-height: 13px
|
40
|
+
font:
|
41
|
+
family: Menlo
|
42
|
+
size: 13px
|
43
|
+
|
44
|
+
ul
|
45
|
+
time
|
46
|
+
font:
|
47
|
+
family: Menlo, monospace
|
48
|
+
size: 13px
|
49
|
+
|
50
|
+
&.tags
|
51
|
+
display: inline
|
52
|
+
li
|
53
|
+
float: left
|
54
|
+
margin: 0 5px
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
// code highlighting
|
59
|
+
code
|
60
|
+
.k
|
61
|
+
color: red
|
62
|
+
|
63
|
+
.nb
|
64
|
+
color: blue
|
65
|
+
|
66
|
+
.nf
|
67
|
+
color: green
|
68
|
+
|
69
|
+
.s2
|
70
|
+
color: grey
|