henshin 0.2.2 → 0.3.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.
Files changed (48) hide show
  1. data/.gitignore +1 -1
  2. data/README.markdown +0 -1
  3. data/Rakefile +4 -1
  4. data/VERSION +1 -1
  5. data/bin/files.rb +46 -0
  6. data/bin/henshin +47 -79
  7. data/henshin.gemspec +37 -14
  8. data/lib/henshin.rb +50 -36
  9. data/lib/henshin/archive.rb +161 -0
  10. data/lib/henshin/categories.rb +6 -1
  11. data/lib/henshin/ext.rb +2 -53
  12. data/lib/henshin/gen.rb +16 -15
  13. data/lib/henshin/plugin.rb +20 -7
  14. data/lib/henshin/plugins/highlight.rb +31 -0
  15. data/lib/henshin/plugins/liquid.rb +48 -14
  16. data/lib/henshin/plugins/maruku.rb +3 -4
  17. data/lib/henshin/plugins/sass.rb +7 -6
  18. data/lib/henshin/plugins/textile.rb +3 -4
  19. data/lib/henshin/post.rb +50 -8
  20. data/lib/henshin/site.rb +60 -34
  21. data/lib/henshin/tags.rb +5 -1
  22. data/test/site/css/{print.sass → includes/reset.sass} +0 -3
  23. data/test/site/css/{screen.css → print.css} +1 -4
  24. data/test/site/css/screen.sass +70 -0
  25. data/test/site/includes/head.html +1 -0
  26. data/test/site/index.html +12 -2
  27. data/test/site/layouts/archive_date.html +19 -0
  28. data/test/site/layouts/archive_month.html +19 -0
  29. data/test/site/layouts/archive_year.html +19 -0
  30. data/test/site/layouts/category_index.html +5 -4
  31. data/test/site/layouts/category_page.html +2 -2
  32. data/test/site/layouts/main.html +1 -36
  33. data/test/site/layouts/post.html +15 -5
  34. data/test/site/layouts/tag_index.html +3 -3
  35. data/test/site/layouts/tag_page.html +2 -2
  36. data/test/site/options.yaml +7 -4
  37. data/test/site/posts/Testing-Stuff.markdown +7 -1
  38. data/test/test_archives.rb +27 -0
  39. data/test/test_categories.rb +0 -0
  40. data/test/test_gens.rb +28 -7
  41. data/test/test_options.rb +4 -2
  42. data/test/test_posts.rb +50 -14
  43. data/test/test_site.rb +55 -7
  44. data/test/test_statics.rb +0 -0
  45. data/test/test_tags.rb +0 -0
  46. data/test/text_exts.rb +0 -0
  47. metadata +86 -17
  48. 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 = Defaults.merge(override)
11
+ @config = {}
12
+ @priority = 5
14
13
  end
15
14
 
16
15
  def generate( content )
@@ -3,7 +3,7 @@ require 'sass'
3
3
 
4
4
  class SassPlugin < Henshin::Generator
5
5
 
6
- attr_accessor :extensions, :config, :opts_name
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
- @opts_name = :sass
14
+ @config = {:ignore_layouts => true,
15
+ :style => :nested}
16
+ @priority = 5
15
17
  end
16
18
 
17
19
  def configure( override )
18
- override ? @config = Defaults.merge(override) : @config = Defaults
20
+ @config.merge!(override) if override
19
21
  end
20
22
 
21
23
  def generate( content )
22
- engine = Sass::Engine.new(content, config)
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 = Defaults.merge(override)
11
+ @config = {}
12
+ @priority = 5
14
13
  end
15
14
 
16
15
  def generate( content )
@@ -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(/-/, ' ').titlize
63
+ override[:title] = data.gsub(/-/, ' ')
64
64
  else
65
- override[:title] = data.titlize
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] if 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' => @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 File.join( write_path.directory )
144
- file = File.new( File.join( write_path ), "w" )
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
@@ -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.read_others
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
- # Gets all other items, and determines whether it's static or needs to be converted
64
- def read_others
65
- path = File.join(config[:root], '**', '*.*')
66
- items = Dir.glob(path)
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
- static = items.select {|i| i.static?(self.config)}
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 {|i| i.to_hash},
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.each_parallel {|g| g.render}
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
@@ -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,6 +1,3 @@
1
- // This is to test whether sass files are successfully created
2
- // and placed in the css folder (or whatever is defined
3
-
4
1
  body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td
5
2
  margin: 0
6
3
  padding: 0
@@ -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