henshin 0.3.0 → 0.4.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.
- data/.gitignore +5 -1
- data/README.markdown +9 -46
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bin/henshin +11 -12
- data/henshin.gemspec +20 -27
- data/lib/henshin.rb +21 -98
- data/lib/henshin/archive.rb +87 -115
- data/{bin → lib/henshin/exec}/files.rb +0 -0
- data/lib/henshin/ext.rb +35 -58
- data/lib/henshin/gen.rb +83 -68
- data/lib/henshin/labels.rb +144 -0
- data/lib/henshin/plugin.rb +70 -33
- data/lib/henshin/plugins/highlight.rb +19 -26
- data/lib/henshin/plugins/liquid.rb +50 -52
- data/lib/henshin/plugins/maruku.rb +14 -16
- data/lib/henshin/plugins/sass.rb +19 -23
- data/lib/henshin/plugins/textile.rb +14 -16
- data/lib/henshin/post.rb +67 -120
- data/lib/henshin/site.rb +154 -131
- data/lib/henshin/static.rb +10 -8
- data/test/helper.rb +20 -8
- data/test/site/css/{includes/reset.sass → _reset.sass} +0 -0
- data/test/site/css/screen.sass +1 -1
- data/test/site/index.html +2 -3
- data/test/site/layouts/archive_date.html +5 -4
- data/test/site/layouts/archive_month.html +10 -5
- data/test/site/layouts/archive_year.html +13 -6
- data/test/site/layouts/category_page.html +7 -7
- data/test/site/layouts/main.html +3 -4
- data/test/site/layouts/post.html +1 -1
- data/test/site/layouts/tag_index.html +3 -2
- data/test/site/layouts/tag_page.html +6 -6
- data/test/site/options.yaml +2 -2
- data/test/site/plugins/test.rb +1 -3
- data/test/site/posts/Testing-Stuff.markdown +1 -1
- data/test/site/posts/Textile-Test.textile +1 -1
- data/test/site/posts/lorem-ipsum.markdown +1 -1
- data/test/site/posts/same-date.markdown +1 -1
- data/test/{test_henshin.rb → suite.rb} +0 -1
- data/test/test_gen.rb +98 -0
- data/test/test_options.rb +34 -19
- data/test/test_post.rb +67 -0
- data/test/test_site.rb +159 -46
- data/test/test_static.rb +13 -0
- metadata +53 -32
- data/lib/henshin/categories.rb +0 -29
- data/lib/henshin/tags.rb +0 -28
- data/test/test_archives.rb +0 -27
- data/test/test_categories.rb +0 -0
- data/test/test_gens.rb +0 -54
- data/test/test_layouts.rb +0 -14
- data/test/test_posts.rb +0 -75
- data/test/test_statics.rb +0 -0
- data/test/test_tags.rb +0 -0
- data/test/text_exts.rb +0 -0
data/lib/henshin/plugin.rb
CHANGED
@@ -1,63 +1,100 @@
|
|
1
1
|
module Henshin
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
class Plugin
|
4
|
+
|
5
|
+
# @return [Hash{:input, :output => Array, String}]
|
6
|
+
# the file extensions that can be read by the plugin and the extension
|
7
|
+
# of the output
|
4
8
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# @extensions = {:input => ['md', 'markdown'],
|
12
|
+
# :output => 'html'}
|
13
|
+
attr_accessor :extensions
|
8
14
|
|
9
|
-
|
15
|
+
# @return [Hash{Symbol => Object}]
|
16
|
+
# the config for the plugin
|
17
|
+
attr_accessor :config
|
10
18
|
|
11
|
-
#
|
19
|
+
# @return [Integer]
|
20
|
+
# The plugins are sorted on priority, high priority plugins are called first.
|
21
|
+
# You could really use any number, but stick to 1 to 5.
|
22
|
+
attr_accessor :priority
|
12
23
|
|
13
|
-
|
14
|
-
|
15
|
-
|
24
|
+
# Create a new instance of Plugin
|
25
|
+
#
|
26
|
+
# @param [Site] site that the plugin belongs to
|
27
|
+
def initialize(site)
|
16
28
|
@extensions = {:input => [],
|
17
29
|
:output => ''}
|
30
|
+
@config = {}
|
31
|
+
@priority = 3
|
18
32
|
end
|
19
33
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
34
|
+
# Finds all classes that subclass this particular class
|
35
|
+
#
|
36
|
+
# @return [Array] an array of class objects
|
37
|
+
# @see http://www.ruby-forum.com/topic/163430
|
38
|
+
# modified from the answer given on ruby-forum by black eyes
|
39
|
+
def self.subclasses
|
40
|
+
r = Henshin.constants.find_all do |c_klass|
|
41
|
+
if (c_klass != c_klass.upcase) && (Henshin.const_get(c_klass).is_a?(Class))
|
42
|
+
self > Henshin.const_get(c_klass)
|
24
43
|
else
|
25
|
-
|
44
|
+
nil
|
26
45
|
end
|
27
|
-
elsif override
|
28
|
-
@config = override
|
29
46
|
end
|
47
|
+
r.collect {|k| Henshin.const_get(k)}
|
30
48
|
end
|
31
49
|
|
50
|
+
# Plugins are sorted by priority
|
32
51
|
def <=>(other)
|
33
52
|
self.priority <=> other.priority
|
34
53
|
end
|
35
54
|
|
36
|
-
|
37
|
-
# Henshin.register! self, :standard_plugin
|
38
|
-
end
|
55
|
+
end
|
39
56
|
|
40
|
-
|
41
|
-
|
57
|
+
# Generator is the plugin type for processing things like markdown
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
#
|
61
|
+
# class MyMarkupPlugin < Henshin::Generator
|
62
|
+
# def generate(content)
|
63
|
+
# MyMarkup.do_stuff(content)
|
64
|
+
# end
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
class Generator < Plugin
|
42
68
|
|
69
|
+
# This is the method that is called when rendering content
|
70
|
+
#
|
71
|
+
# @param [String] content to be rendered
|
72
|
+
# @return [String]
|
43
73
|
def generate( content )
|
44
|
-
# return string
|
45
74
|
end
|
46
|
-
|
47
|
-
# Uncomment to have the plugin loaded
|
48
|
-
# Henshin.register! self, :generator
|
75
|
+
|
49
76
|
end
|
50
77
|
|
51
|
-
|
52
|
-
|
78
|
+
# Layoutor is the plugin type for things like liquid
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
#
|
82
|
+
# class MyLayoutPlugin < Henshin::Layoutor
|
83
|
+
# def generate(content, data)
|
84
|
+
# MyLayout.do_stuff(content).render(data)
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
class Layoutor < Plugin
|
53
89
|
|
54
|
-
#
|
55
|
-
|
56
|
-
|
90
|
+
# This is the method called when rendering content
|
91
|
+
#
|
92
|
+
# @param [String] content to be rendered
|
93
|
+
# @param [Hash] data to be put into the content
|
94
|
+
# @return [String]
|
95
|
+
def generate( content, data )
|
57
96
|
end
|
58
97
|
|
59
|
-
# Uncomment to have the plugin loaded
|
60
|
-
# Henshin.register! self, :generator
|
61
98
|
end
|
62
99
|
|
63
100
|
end
|
@@ -1,31 +1,24 @@
|
|
1
|
-
require 'henshin/plugin'
|
2
1
|
require 'simplabs/highlight'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
insert = '<pre><code>' + Simplabs::Highlight.highlight(lang, code) + '</code></pre>'
|
24
|
-
content.gsub(/(\$highlight.*\$end)/m, insert)
|
25
|
-
else
|
26
|
-
content
|
3
|
+
module Henshin
|
4
|
+
class HighlightPlugin < Generator
|
5
|
+
|
6
|
+
def initialize(site)
|
7
|
+
@extensions = {:input => ['*']}
|
8
|
+
@config = {}
|
9
|
+
@priority = 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate( content )
|
13
|
+
content =~ /(\$highlight)\s+(.+)((\n.*)+)(\$end)/
|
14
|
+
if $1
|
15
|
+
lang = $2.to_sym
|
16
|
+
code = $3[1..-1] # removes first new line
|
17
|
+
insert = '<pre><code>' + Simplabs::Highlight.highlight(lang, code) + '</code></pre>'
|
18
|
+
content.gsub(/(\$highlight.*\$end)/m, insert)
|
19
|
+
else
|
20
|
+
content
|
21
|
+
end
|
27
22
|
end
|
28
23
|
end
|
29
|
-
|
30
|
-
Henshin.register! self
|
31
24
|
end
|
@@ -1,63 +1,61 @@
|
|
1
|
-
require 'henshin/plugin'
|
2
1
|
require 'liquid'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
attr_accessor :config
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@config = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def configure( override )
|
13
|
-
@config.merge!(override) if override
|
14
|
-
end
|
15
|
-
|
16
|
-
def generate( layout, data )
|
17
|
-
reg = {:include_dir => @config['include_dir']}
|
18
|
-
Liquid::Template.parse(layout).render(data, :registers => reg)
|
19
|
-
end
|
20
|
-
|
21
|
-
module Filters
|
22
|
-
def date_to_string(dt)
|
23
|
-
dt.strftime "%d %b %Y"
|
24
|
-
end
|
3
|
+
module Henshin
|
4
|
+
class LiquidPlugin < Layoutor
|
25
5
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
6
|
+
def initialize(site)
|
7
|
+
@config = {}
|
8
|
+
|
9
|
+
if site.config['liquid']
|
10
|
+
@config = site.config['liquid']
|
11
|
+
@config['include_dir'] = File.join(site.root, @config['include_dir'])
|
12
|
+
end
|
32
13
|
end
|
33
14
|
|
34
|
-
def
|
35
|
-
|
15
|
+
def generate( content, data )
|
16
|
+
reg = {:include_dir => @config['include_dir']}
|
17
|
+
Liquid::Template.parse(content).render(data, :registers => reg)
|
36
18
|
end
|
37
19
|
|
38
|
-
|
39
|
-
|
40
|
-
|
20
|
+
module Filters
|
21
|
+
def date_to_string(dt)
|
22
|
+
dt.strftime "%d %b %Y"
|
23
|
+
end
|
24
|
+
|
25
|
+
def date_to_long(dt)
|
26
|
+
dt.strftime "%d %B %Y at %H:%M"
|
27
|
+
end
|
41
28
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
29
|
+
def time_to_string(dt)
|
30
|
+
dt.strtime "%H:%M"
|
31
|
+
end
|
32
|
+
|
33
|
+
def titlecase(str)
|
34
|
+
str.upcase
|
35
|
+
end
|
36
|
+
|
37
|
+
def escape(str)
|
38
|
+
CGI::escape str
|
39
|
+
end
|
40
|
+
|
41
|
+
def escape_html(str)
|
42
|
+
CGI::escapeHTML str
|
43
|
+
end
|
44
|
+
end
|
45
|
+
Liquid::Template.register_filter(Filters)
|
46
|
+
|
47
|
+
class Include < Liquid::Tag
|
48
|
+
def initialize(tag_name, file, tokens)
|
49
|
+
super
|
50
|
+
@file = file.strip
|
51
|
+
end
|
52
|
+
|
53
|
+
def render(context)
|
54
|
+
include = File.join(context.registers[:include_dir], @file)
|
55
|
+
File.open(include, 'r') {|f| f.read}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
Liquid::Template.register_tag('include', Include)
|
53
59
|
|
54
|
-
def render(context)
|
55
|
-
include = File.join(context.registers[:include_dir], @file)
|
56
|
-
File.open(include, 'r') {|f| f.read}
|
57
|
-
end
|
58
60
|
end
|
59
|
-
Liquid::Template.register_tag('include', Include)
|
60
|
-
|
61
|
-
Henshin.register! self, :liquid
|
62
61
|
end
|
63
|
-
|
@@ -1,20 +1,18 @@
|
|
1
|
-
require 'henshin/plugin'
|
2
1
|
require 'maruku'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
module Henshin
|
4
|
+
class MarukuPlugin < Generator
|
5
|
+
|
6
|
+
def initialize(site)
|
7
|
+
@extensions = {:input => ['markdown', 'mkdwn', 'md'],
|
8
|
+
:output => 'html'}
|
9
|
+
@config = {}
|
10
|
+
@priority = 5
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate( content )
|
14
|
+
Maruku.new(content).to_html
|
15
|
+
end
|
16
|
+
|
13
17
|
end
|
14
|
-
|
15
|
-
def generate( content )
|
16
|
-
Maruku.new(content).to_html
|
17
|
-
end
|
18
|
-
|
19
|
-
Henshin.register! self
|
20
18
|
end
|
data/lib/henshin/plugins/sass.rb
CHANGED
@@ -1,28 +1,24 @@
|
|
1
|
-
require 'henshin/plugin'
|
2
1
|
require 'sass'
|
3
2
|
|
4
|
-
|
3
|
+
module Henshin
|
4
|
+
class SassPlugin < Generator
|
5
|
+
|
6
|
+
def initialize(site)
|
7
|
+
@extensions = {:input => ['sass', 'scss'],
|
8
|
+
:output => 'css'}
|
9
|
+
@config = {'ignore_layouts' => true,
|
10
|
+
'style' => :nested,
|
11
|
+
'load_paths' => Dir.glob((site.root + '*').to_s),
|
12
|
+
'syntax' => :sass}
|
5
13
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
:style => :nested}
|
16
|
-
@priority = 5
|
17
|
-
end
|
18
|
-
|
19
|
-
def configure( override )
|
20
|
-
@config.merge!(override) if override
|
21
|
-
end
|
22
|
-
|
23
|
-
def generate( content )
|
24
|
-
Sass::Engine.new(content, @config).render
|
14
|
+
@config.merge!(site.config['sass']) if site.config['sass']
|
15
|
+
|
16
|
+
@priority = 5
|
17
|
+
end
|
18
|
+
|
19
|
+
def generate( content )
|
20
|
+
Sass::Engine.new(content, @config.to_options).render
|
21
|
+
end
|
22
|
+
|
25
23
|
end
|
26
|
-
|
27
|
-
Henshin.register! self, :sass
|
28
24
|
end
|
@@ -1,20 +1,18 @@
|
|
1
|
-
require 'henshin/plugin'
|
2
1
|
require 'redcloth'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
3
|
+
module Henshin
|
4
|
+
class TextilePlugin < Generator
|
5
|
+
|
6
|
+
def initialize(site)
|
7
|
+
@extensions = {:input => ['textile'],
|
8
|
+
:output => 'html'}
|
9
|
+
@config = {}
|
10
|
+
@priority = 5
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate( content )
|
14
|
+
RedCloth.new(content).to_html
|
15
|
+
end
|
16
|
+
|
17
17
|
end
|
18
|
-
|
19
|
-
Henshin.register! self
|
20
18
|
end
|
data/lib/henshin/post.rb
CHANGED
@@ -2,112 +2,55 @@ module Henshin
|
|
2
2
|
|
3
3
|
class Post < Gen
|
4
4
|
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :path, :data, :content, :site, :layout, :generators
|
6
6
|
|
7
7
|
def initialize( path, site )
|
8
8
|
@path = path
|
9
9
|
@site = site
|
10
|
-
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
|
15
|
-
@
|
10
|
+
|
11
|
+
@content = ''
|
12
|
+
@data = {}
|
13
|
+
@generators = []
|
14
|
+
|
15
|
+
@data['input'] = @path.extname[1..-1]
|
16
16
|
end
|
17
17
|
|
18
18
|
|
19
19
|
##
|
20
|
-
#
|
21
|
-
def
|
20
|
+
# Reads the file
|
21
|
+
def read
|
22
22
|
self.read_name
|
23
|
-
self.
|
23
|
+
self.read_file if @path.exist?
|
24
|
+
self.get_generators
|
25
|
+
self.get_layout
|
26
|
+
|
27
|
+
# now tidy up data
|
28
|
+
@data['output'] ||= @data['input']
|
29
|
+
@data['date'] = Time.parse(@data['date'])
|
30
|
+
@data['tags'] = @data['tags'].flatten.uniq if @data['tags']
|
31
|
+
self
|
24
32
|
end
|
25
33
|
|
26
34
|
# Reads the filename and extracts information from it
|
27
35
|
def read_name
|
28
|
-
|
29
|
-
parser = {'title' => '([a-zA-Z0-9 ]+)',
|
30
|
-
'title-with-dashes' => '([a-zA-Z0-9-]+)',
|
31
|
-
'date' => '(\d{4}-\d{2}-\d{2})',
|
32
|
-
'date-time' => '(\d{4}-\d{2}-\d{2} at \d{2}:\d{2})',
|
33
|
-
'xml-date-time' => '(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?((\+|-)\d{2}:\d{2})?)',
|
34
|
-
'category' => '([a-zA-Z0-9_ -]+)',
|
35
|
-
'extension' => "([a-zA-Z0-9_-]+)"}
|
36
36
|
|
37
|
-
|
38
|
-
data_order = []
|
37
|
+
result = Parsey.parse(@path.to_s[(@site.root + 'posts').to_s.size..-1], @site.config['file_name'], Partials)
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
data_order.unshift( 'optional' )
|
50
|
-
"(#{$1})?"
|
51
|
-
end
|
52
|
-
|
53
|
-
# convert string to actual regex
|
54
|
-
matcher = Regexp.new(m)
|
55
|
-
|
56
|
-
override = {}
|
57
|
-
name = @path[ (config[:root]+'/posts/').size..-1 ]
|
58
|
-
|
59
|
-
file_data = name.match( matcher ).captures
|
60
|
-
file_data.each_with_index do |data, i|
|
61
|
-
if data_order[i].include? 'title'
|
62
|
-
if data_order[i].include? 'dashes'
|
63
|
-
override[:title] = data.gsub(/-/, ' ')
|
64
|
-
else
|
65
|
-
override[:title] = data
|
39
|
+
result.each do |k, v|
|
40
|
+
unless v.nil?
|
41
|
+
case k
|
42
|
+
when 'title-with-dashes'
|
43
|
+
@data['title'] = v.gsub(/-/, ' ').titlecase
|
44
|
+
when 'title'
|
45
|
+
@data['title'] = v.titlecase
|
46
|
+
else
|
47
|
+
@data[k] = v
|
66
48
|
end
|
67
|
-
elsif data_order[i].include? 'date'
|
68
|
-
override[:date] = data
|
69
|
-
elsif data_order[i].include? 'extension'
|
70
|
-
override[:extension] = data
|
71
|
-
elsif data_order[i].include? 'category'
|
72
|
-
override[:category] = data
|
73
49
|
end
|
74
50
|
end
|
75
|
-
self.override( override )
|
76
|
-
end
|
77
|
-
|
78
|
-
# Reads the files yaml frontmatter and uses it to override some settings, then grabs content
|
79
|
-
def read_yaml
|
80
|
-
file = File.read(self.path)
|
81
|
-
|
82
|
-
if file =~ /^(---\s*\n.*?\n?^---\s*$\n?)/m
|
83
|
-
override = YAML.load_file(@path).to_options
|
84
|
-
self.override(override)
|
85
|
-
@content = file[$1.size..-1]
|
86
|
-
else
|
87
|
-
@content = file
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Uses the loaded data to override settings
|
92
|
-
#
|
93
|
-
# @param [Hash] override data to override settings with
|
94
|
-
def override( override )
|
95
|
-
@title = override[:title].titlecase if override[:title]
|
96
|
-
@layout = @site.layouts[ override[:layout] ] if override[:layout]
|
97
|
-
@date = Time.parse( override[:date] ) if override[:date]
|
98
|
-
@tags = override[:tags].split(', ') if override[:tags]
|
99
|
-
@category = override[:category] if override[:category]
|
100
|
-
@author = override[:author] if override[:author]
|
101
|
-
@extension = override[:extension] if override[:extension]
|
102
|
-
@category = override[:category] if override[:category]
|
103
51
|
|
104
|
-
if override[:tags]
|
105
|
-
@tags << override[:tags].split(', ')
|
106
|
-
@tags.flatten!.uniq!
|
107
|
-
end
|
108
52
|
end
|
109
53
|
|
110
|
-
|
111
54
|
# Creates the data to be sent to the layout engine
|
112
55
|
#
|
113
56
|
# @return [Hash] the payload for the layout engine
|
@@ -117,8 +60,8 @@ module Henshin
|
|
117
60
|
'site' => @site.payload['site'],
|
118
61
|
'post' => self.to_hash
|
119
62
|
}
|
120
|
-
r['post']['next'] = self.next.to_hash if self.next
|
121
|
-
r['post']['prev'] = self.prev.to_hash if self.prev
|
63
|
+
#r['post']['next'] = self.next.to_hash if self.next
|
64
|
+
#r['post']['prev'] = self.prev.to_hash if self.prev
|
122
65
|
r
|
123
66
|
end
|
124
67
|
|
@@ -126,20 +69,34 @@ module Henshin
|
|
126
69
|
#
|
127
70
|
# @return [Hash]
|
128
71
|
def to_hash
|
129
|
-
|
130
|
-
|
131
|
-
|
72
|
+
if @hashed
|
73
|
+
@hashed
|
74
|
+
else
|
75
|
+
@hashed = @data.dup
|
76
|
+
@hashed['content'] = @content
|
77
|
+
@hashed['url'] = self.url
|
78
|
+
@hashed['permalink'] = self.permalink
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
if @data['tags']
|
83
|
+
@hashed['tags'] = []
|
84
|
+
@site.tags.select{|t| @data['tags'].include?(t.name)}.each do |tag|
|
85
|
+
# can't call Tag#to_hash or it creates an infinite loop!
|
86
|
+
@hashed['tags'] << {'name' => tag.name, 'url' => tag.url}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
if @data['category']
|
91
|
+
@site.categories.each do |cat|
|
92
|
+
if cat.name == @data['category']
|
93
|
+
@hashed['category'] = {'name' => cat.name, 'url' => cat.url}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
@hashed
|
132
99
|
end
|
133
|
-
{
|
134
|
-
'title' => @title,
|
135
|
-
'author' => @author,
|
136
|
-
'permalink' => self.permalink,
|
137
|
-
'url' => self.url,
|
138
|
-
'date' => @date,
|
139
|
-
'category' => @category,
|
140
|
-
'tags' => tags,
|
141
|
-
'content' => @content
|
142
|
-
}
|
143
100
|
end
|
144
101
|
|
145
102
|
# Gets the post after this one
|
@@ -167,32 +124,22 @@ module Henshin
|
|
167
124
|
end
|
168
125
|
end
|
169
126
|
end
|
170
|
-
|
171
|
-
|
172
|
-
##
|
173
|
-
# Writes the file to the correct place
|
174
|
-
def write
|
175
|
-
write_path = File.join( config[:root], config[:target], permalink )
|
176
|
-
FileUtils.mkdir_p write_path.directory
|
177
|
-
file = File.new( write_path, "w" )
|
178
|
-
file.puts( @content )
|
179
|
-
end
|
180
127
|
|
181
|
-
#
|
128
|
+
# @return [String] the permalink of the post
|
182
129
|
def permalink
|
183
|
-
partials = {'year' =>
|
184
|
-
'month' =>
|
185
|
-
'date' =>
|
186
|
-
'title' =>
|
187
|
-
'category' =>
|
130
|
+
partials = {'year' => @data['date'].year,
|
131
|
+
'month' => @data['date'].month,
|
132
|
+
'date' => @data['date'].day,
|
133
|
+
'title' => @data['title'].slugify,
|
134
|
+
'category' => @data['category'] || ''}
|
188
135
|
|
189
|
-
config[
|
190
|
-
|
191
|
-
end
|
136
|
+
perm = @site.config['permalink'].gsub(/\{([a-z-]+)\}/) { partials[$1] }
|
137
|
+
File.join(@site.base, perm)
|
192
138
|
end
|
193
139
|
|
140
|
+
# Sorts on date first, then permalink if dates are equal
|
194
141
|
def <=>(other)
|
195
|
-
s =
|
142
|
+
s = @data['date'] <=> other.data['date']
|
196
143
|
if s == 0
|
197
144
|
self.permalink <=> other.permalink
|
198
145
|
else
|