henshin 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +5 -1
  2. data/README.markdown +9 -46
  3. data/Rakefile +2 -1
  4. data/VERSION +1 -1
  5. data/bin/henshin +11 -12
  6. data/henshin.gemspec +20 -27
  7. data/lib/henshin.rb +21 -98
  8. data/lib/henshin/archive.rb +87 -115
  9. data/{bin → lib/henshin/exec}/files.rb +0 -0
  10. data/lib/henshin/ext.rb +35 -58
  11. data/lib/henshin/gen.rb +83 -68
  12. data/lib/henshin/labels.rb +144 -0
  13. data/lib/henshin/plugin.rb +70 -33
  14. data/lib/henshin/plugins/highlight.rb +19 -26
  15. data/lib/henshin/plugins/liquid.rb +50 -52
  16. data/lib/henshin/plugins/maruku.rb +14 -16
  17. data/lib/henshin/plugins/sass.rb +19 -23
  18. data/lib/henshin/plugins/textile.rb +14 -16
  19. data/lib/henshin/post.rb +67 -120
  20. data/lib/henshin/site.rb +154 -131
  21. data/lib/henshin/static.rb +10 -8
  22. data/test/helper.rb +20 -8
  23. data/test/site/css/{includes/reset.sass → _reset.sass} +0 -0
  24. data/test/site/css/screen.sass +1 -1
  25. data/test/site/index.html +2 -3
  26. data/test/site/layouts/archive_date.html +5 -4
  27. data/test/site/layouts/archive_month.html +10 -5
  28. data/test/site/layouts/archive_year.html +13 -6
  29. data/test/site/layouts/category_page.html +7 -7
  30. data/test/site/layouts/main.html +3 -4
  31. data/test/site/layouts/post.html +1 -1
  32. data/test/site/layouts/tag_index.html +3 -2
  33. data/test/site/layouts/tag_page.html +6 -6
  34. data/test/site/options.yaml +2 -2
  35. data/test/site/plugins/test.rb +1 -3
  36. data/test/site/posts/Testing-Stuff.markdown +1 -1
  37. data/test/site/posts/Textile-Test.textile +1 -1
  38. data/test/site/posts/lorem-ipsum.markdown +1 -1
  39. data/test/site/posts/same-date.markdown +1 -1
  40. data/test/{test_henshin.rb → suite.rb} +0 -1
  41. data/test/test_gen.rb +98 -0
  42. data/test/test_options.rb +34 -19
  43. data/test/test_post.rb +67 -0
  44. data/test/test_site.rb +159 -46
  45. data/test/test_static.rb +13 -0
  46. metadata +53 -32
  47. data/lib/henshin/categories.rb +0 -29
  48. data/lib/henshin/tags.rb +0 -28
  49. data/test/test_archives.rb +0 -27
  50. data/test/test_categories.rb +0 -0
  51. data/test/test_gens.rb +0 -54
  52. data/test/test_layouts.rb +0 -14
  53. data/test/test_posts.rb +0 -75
  54. data/test/test_statics.rb +0 -0
  55. data/test/test_tags.rb +0 -0
  56. data/test/text_exts.rb +0 -0
@@ -1,4 +1,4 @@
1
- @import includes/reset.css
1
+ @import _reset.sass
2
2
 
3
3
  body
4
4
  width: 500px
@@ -3,7 +3,6 @@ layout: main
3
3
  title: Home Page
4
4
  ---
5
5
 
6
-
7
6
  <header>
8
7
  <h1>{{ gen.title }}</h1>
9
8
  </header>
@@ -19,6 +18,6 @@ title: Home Page
19
18
  </ul>
20
19
 
21
20
  <ul>
22
- <li><a href="/categories/">Categories</a></li>
23
- <li><a href="/tags/">Tags</a></li>
21
+ <li><a href="/category/">Categories</a></li>
22
+ <li><a href="/tag/">Tags</a></li>
24
23
  </ul>
@@ -6,12 +6,13 @@
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
+ <a href="/">Home</a>
10
+ <h1>Archive for {{ archive.year }}/{{ archive.month }}/{{ archive.day }}</h1>
9
11
 
10
- <h2>{{ archive.date }}</h2>
11
12
  <ul>
12
- {% for post in archive.posts %}
13
- <li><a href="{{ post.url }}">{{ post.title }}</a></li>
14
- {% endfor %}
13
+ {% for post in archive.posts[archive.year][archive.month][archive.day] %}
14
+ <li><a href="{{ post.url }}">{{ post.title }}</a></li>
15
+ {% endfor %}
15
16
  </ul>
16
17
 
17
18
  <span>Copyright &copy; {{ site.author }}</span>
@@ -6,12 +6,17 @@
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
-
10
- <h2>{{ archive.date }}</h2>
9
+ <a href="/">Home</a>
10
+ <h1>Archive for {{ archive.year }}/{{ archive.month }}</h1>
11
+
11
12
  <ul>
12
- {% for post in archive.posts %}
13
- <li><a href="{{ post.url }}">{{ post.title }}</a></li>
14
- {% endfor %}
13
+ {% for day in (1..31) %}
14
+ {% if archive.posts[archive.year][archive.month][day] %}
15
+ {% for post in archive.posts[archive.year][archive.month][day] %}
16
+ <li><a href="{{ post.url }}">{{ post.title }}</a></li>
17
+ {% endfor %}
18
+ {% endif %}
19
+ {% endfor %}
15
20
  </ul>
16
21
 
17
22
  <span>Copyright &copy; {{ site.author }}</span>
@@ -6,14 +6,21 @@
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
-
10
- <h2>{{ archive.date }}</h2>
9
+ <a href="/">Home</a>
10
+ <h1>Archive for {{ archive.year }}</h1>
11
+
11
12
  <ul>
12
- {% for post in archive.posts %}
13
- <li><a href="{{ post.url }}">{{ post.title }}</a></li>
14
- {% endfor %}
13
+ {% for day in (1..31) %}
14
+ {% for month in (1..12) %}
15
+ {% if archive.posts[archive.year][month][day] %}
16
+ {% for post in archive.posts[archive.year][month][day] %}
17
+ <li><a href="{{ post.url }}">{{ post.title }}</a></li>
18
+ {% endfor %}
19
+ {% endif %}
20
+ {% endfor %}
21
+ {% endfor %}
15
22
  </ul>
16
-
23
+
17
24
  <span>Copyright &copy; {{ site.author }}</span>
18
25
  </body>
19
26
  </html>
@@ -6,14 +6,14 @@
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
-
10
- <h2>{{ category.name }}</h2>
9
+ <a href="/">Home</a>
11
10
 
12
- <ul>
13
- {% for post in category.posts %}
14
- <li><time>{{ post.date | date_to_string }}</time> - <a href="{{ post.url }}">{{ post.title }}</a></li>
15
- {% endfor %}
16
- </ul>
11
+ <h2>{{ category.name }}</h2>
12
+ <ul>
13
+ {% for post in category.posts %}
14
+ <li><time>{{ post.date | date_to_string }}</time> - <a href="{{ post.url }}">{{ post.title }}</a></li>
15
+ {% endfor %}
16
+ </ul>
17
17
 
18
18
  <span>Copyright &copy; {{ site.author }}</span>
19
19
  </body>
@@ -2,13 +2,12 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <title>{{ site.title }}</title>
5
+ <title>{{ gen.title }}</title>
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
9
 
10
- {{ yield }}
11
-
12
- <span>Copyright &copy; {{ site.author }}</span>
10
+ {{ yield }}
11
+
13
12
  </body>
14
13
  </html>
@@ -31,6 +31,6 @@
31
31
 
32
32
  {{ yield }}
33
33
 
34
- <span>Copyright &copy; {{ post.author }}</span>
34
+ <span>Copyright &copy; {% if post.author %}{{ post.author }}{% else %}{{ site.author }}{% endif %}</span>
35
35
  </body>
36
36
  </html>
@@ -2,11 +2,12 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <title>{{ site.title }}</title>
5
+ <title>{{ site.title }} > Tags</title>
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
-
9
+ <a href="/">Home</a>
10
+
10
11
  <h2>A List of Tags</h2>
11
12
  <ul>
12
13
  {% for tag in site.tags %}
@@ -6,14 +6,14 @@
6
6
  {% include head.html %}
7
7
  </head>
8
8
  <body>
9
+ <a href="/">Home</a>
9
10
 
10
11
  <h2>{{ tag.name }}</h2>
11
-
12
- <ul>
13
- {% for post in tag.posts %}
14
- <li><time>{{ post.date | date_to_string }}</time> - <a href="{{ post.url }}">{{ post.title }}</a></li>
15
- {% endfor %}
16
- </ul>
12
+ <ul>
13
+ {% for post in tag.posts %}
14
+ <li><time>{{ post.date | date_to_string }}</time> - <a href="{{ post.url }}">{{ post.title }}</a></li>
15
+ {% endfor %}
16
+ </ul>
17
17
 
18
18
  <span>Copyright &copy; {{ site.author }}</span>
19
19
  </body>
@@ -5,10 +5,10 @@ author: Joshua Hawxwell
5
5
 
6
6
  layout: post
7
7
 
8
- exclude: ['includes']
8
+ exclude: ['includes', 'css/_reset.sass']
9
9
  post_name: '{title-with-dashes}.{extension}'
10
10
  permalink: '/{year}/{month}/{date}/{title}/index.html'
11
- plugins: [maruku, sass, pygments, liquid, test, textile, highlight]
11
+ plugins: [maruku, sass, liquid, test, textile, highlight]
12
12
 
13
13
  sass:
14
14
  style: :compact
@@ -1,5 +1,3 @@
1
- require 'henshin/plugin'
2
-
3
- class TestPlugin < Henshin::StandardPlugin
1
+ class TestPlugin < Henshin::Plugin
4
2
 
5
3
  end
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Testing Stuff
3
3
  date: 2010-10-20 at 17:33:23
4
- tags: test, markdown
4
+ tags: [test, markdown]
5
5
  category: test
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Textile Test
3
3
  date: 2009-11-09 at 13:23:47
4
- tags: test, plugin
4
+ tags: [test, plugin]
5
5
  ---
6
6
 
7
7
  So Lorem ipsum dolor sit _amet, consectetur_ adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris *nisi ut aliquip* ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Lorem Ipsum
3
3
  date: 2010-05-15 at 13:23:47
4
- tags: test, lorem
4
+ tags: [test, lorem]
5
5
  ---
6
6
 
7
7
  So Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Same Date as "Lorem Ipsum"
3
3
  date: 2010-05-15 at 13:23:47
4
- tags: test, lorem
4
+ tags: [test, lorem]
5
5
  ---
6
6
 
7
7
  So Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__) ,'helper')
2
2
 
3
3
  test_files = Dir.glob( File.join(File.dirname(__FILE__), "test_*.rb") )
4
- test_files -= [File.join(File.dirname(__FILE__), 'test_henshin.rb')] # don't include self!
5
4
  test_files.each {|f| require f }
@@ -0,0 +1,98 @@
1
+ require File.join(File.dirname(__FILE__) ,'helper')
2
+
3
+ class TestGen < Test::Unit::TestCase
4
+ context "A gen" do
5
+
6
+ setup do
7
+ @site = Henshin::Site.new(site_override).read.process
8
+ @index = "#{root_dir}/index.html"
9
+ @sass = "#{root_dir}/css/screen.sass"
10
+ remove_site
11
+ end
12
+
13
+ def new_sass_gen
14
+ Henshin::Gen.new(@sass.to_p, @site)
15
+ end
16
+
17
+ def new_html_gen
18
+ Henshin::Gen.new(@index.to_p, @site)
19
+ end
20
+
21
+ should "be have file data read" do
22
+ gen = new_html_gen
23
+ gen.read_file
24
+
25
+ assert_equal 'Home Page', gen.data['title']
26
+ assert_equal "main", gen.data['layout']
27
+ end
28
+
29
+ should "be rendered" do
30
+ gen = new_html_gen
31
+ gen.read
32
+ gen2 = new_html_gen
33
+ gen2.read
34
+ gen2.render
35
+ assert_not_equal gen.content, gen2.content
36
+ end
37
+
38
+ should "get output extension from plugin" do
39
+ gen = new_sass_gen
40
+ gen.read
41
+ assert_equal 'sass', gen.data['input']
42
+ assert_equal 'css', gen.data['output']
43
+ end
44
+
45
+ should "render with correct layout" do
46
+ gen = new_html_gen
47
+ # index.html should use 'main'
48
+ gen.read
49
+ gen.render
50
+ l = File.open("#{root_dir}/layouts/main.html", 'r') {|f| f.read}
51
+ assert_equal l, gen.data['layout']
52
+ end
53
+
54
+ should "have the correct permalink" do
55
+ gen = new_html_gen
56
+ gen.read
57
+ assert_equal '/index.html', gen.permalink
58
+ end
59
+
60
+ should "have the correct url" do
61
+ gen = new_html_gen
62
+ gen.read
63
+ assert_equal '/', gen.url
64
+ end
65
+
66
+ should "be written to the correct place" do
67
+ gen = new_html_gen
68
+ gen.read
69
+ assert_equal "#{target_dir}/index.html".to_p, gen.write_path
70
+ end
71
+
72
+ should "write with the correct output" do
73
+ gen = new_sass_gen
74
+ gen.read
75
+ assert_equal "#{target_dir}/css/screen.css".to_p, gen.write_path
76
+ end
77
+
78
+ should "turn all data to hash" do
79
+ gen = new_html_gen
80
+ gen.read
81
+ assert gen.to_hash.is_a? Hash
82
+ end
83
+
84
+ should "insert optional payload" do
85
+ gen = Henshin::Gen.new(@index.to_p, @site, {:name => 'test', :payload => {'data' => 'to_test'}})
86
+ gen.read
87
+ assert_equal 'to_test', gen.payload['test']['data']
88
+ end
89
+
90
+ should "be sortable" do
91
+ gen = new_html_gen
92
+ gen2 = new_sass_gen
93
+ gens = [gen, gen2]
94
+ assert_equal gens.reverse, gens.sort
95
+ end
96
+
97
+ end
98
+ end
@@ -12,11 +12,9 @@ class TestOptions < Test::Unit::TestCase
12
12
  should "warn of invalid options.yaml" do
13
13
  mock(YAML).load_file(@opts) {"boo"}
14
14
  mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
15
- mock($stderr).puts("-> undefined method `to_options' for \"boo\":String")
15
+ mock($stderr).puts("-> can't convert String into Hash")
16
16
 
17
- configured = Henshin.configure
18
- configured[:plugins] = ["maruku", "liquid"]
19
- assert_equal Henshin::Defaults, configured
17
+ assert_equal Henshin::Defaults, Henshin::Site.new.config
20
18
  end
21
19
 
22
20
  should "warn of no options.yaml" do
@@ -24,34 +22,51 @@ class TestOptions < Test::Unit::TestCase
24
22
  mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
25
23
  mock($stderr).puts("-> No such file or directory - #{@opts}")
26
24
 
27
- configured = Henshin.configure
28
- configured[:plugins] = ["maruku", "liquid"]
29
- assert_equal Henshin::Defaults, configured
25
+ assert_equal Henshin::Defaults, Henshin::Site.new.config
30
26
  end
31
27
 
32
28
  should "use defaults if no options.yaml" do
33
29
  mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
34
30
  mock($stderr).puts("-> No such file or directory - #{@opts}")
35
-
36
- configured = Henshin.configure
37
- configured[:plugins] = ["maruku", "liquid"]
38
- assert_equal Henshin::Defaults, configured
31
+
32
+ assert_equal Henshin::Defaults, Henshin::Site.new.config
39
33
  end
40
34
 
41
35
  should "merge override with defaults" do
42
36
  mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
43
37
  mock($stderr).puts("-> No such file or directory - #{@opts}")
44
38
 
45
- override = {:time_zone => '+01:00'}
46
- configured = Henshin.configure(override)
47
- assert_equal '+01:00', configured[:time_zone]
39
+ override = {'time_zone' => '+01:00'}
40
+ site = Henshin::Site.new(override)
41
+ assert_equal '+01:00', site.config['time_zone']
42
+ end
43
+
44
+ should "add special directories to exclude after loading" do
45
+ mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
46
+ mock($stderr).puts("-> No such file or directory - #{@opts}")
47
+ site = Henshin::Site.new
48
+ to_ignore = ['/_site', '/plugins']
49
+ assert_equal to_ignore, site.config['exclude']
50
+
51
+ mock(YAML).load_file(@opts) { {'exclude' => ['/my_dir', 'my_file.txt']} }
52
+ site2 = Henshin::Site.new
53
+ to_ignore = ['/my_dir', 'my_file.txt', '/_site', '/plugins']
54
+ assert_equal to_ignore, site2.config['exclude']
48
55
  end
49
56
 
50
- should "load plugins" do
51
- opts = Henshin::Defaults.dup
52
- opts[:plugins] = ['maruku']
53
- loaded = Henshin.load_plugins(opts)
54
- assert loaded[0].is_a? MarukuPlugin
57
+ should "convert root, target to Pathnames" do
58
+ mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
59
+ mock($stderr).puts("-> No such file or directory - #{@opts}")
60
+ site = Henshin::Site.new
61
+ assert site.root.is_a? Pathname
62
+ assert site.target.is_a? Pathname
63
+ end
64
+
65
+ should "set base" do
66
+ mock($stderr).puts("\nCould not read configuration, falling back to defaults...")
67
+ mock($stderr).puts("-> No such file or directory - #{@opts}")
68
+ site = Henshin::Site.new
69
+ assert site.base
55
70
  end
56
71
 
57
72
  end
@@ -0,0 +1,67 @@
1
+ require File.join(File.dirname(__FILE__) ,'helper')
2
+
3
+ class TestPost < Test::Unit::TestCase
4
+ context "A post" do
5
+
6
+ setup do
7
+ @site = Henshin::Site.new(site_override)
8
+ @post = "#{root_dir}/posts/lorem-ipsum.markdown"
9
+ @post_with_date = "#{root_dir}/posts/2010-08-10-lorem-ipsum.markdown"
10
+ remove_site
11
+ end
12
+
13
+ should "get data from filename" do
14
+ site = @site.dup
15
+ site.config['file_name'] = "{date}-{title-with-dashes}.{extension}"
16
+ post = Henshin::Post.new(@post_with_date.to_p, site)
17
+ post.read_name
18
+ assert_equal 'Lorem Ipsum', post.data['title']
19
+ assert_equal '2010-08-10', post.data['date']
20
+ assert_equal 'markdown', post.data['input']
21
+ end
22
+
23
+ should "turn date to Time object" do
24
+ post = Henshin::Post.new(@post.to_p, @site)
25
+ post.read
26
+ assert post.data['date'].is_a? Time
27
+ end
28
+
29
+ should "get next post" do
30
+
31
+ end
32
+
33
+ should "get previous post" do
34
+
35
+ end
36
+
37
+ should "have correct permalink" do
38
+ site = @site.dup
39
+ site.config['file_name'] = "{date}-{title-with-dashes}.{extension}"
40
+ post = Henshin::Post.new(@post_with_date.to_p, @site)
41
+ post.read
42
+ assert_equal '/2010/8/10/lorem-ipsum/index.html', post.permalink
43
+ end
44
+
45
+ should "have correct url" do
46
+ site = @site.dup
47
+ site.config['file_name'] = "{date}-{title-with-dashes}.{extension}"
48
+ post = Henshin::Post.new(@post_with_date.to_p, @site)
49
+ post.read
50
+ assert_equal '/2010/8/10/lorem-ipsum', post.url
51
+ end
52
+
53
+ should "be written to the correct place" do
54
+ site = @site.dup
55
+ site.config['file_name'] = "{date}-{title-with-dashes}.{extension}"
56
+ post = Henshin::Post.new(@post_with_date.to_p, @site)
57
+ post.read
58
+ path = Pathname.new("#{root_dir}/_site/2010/8/10/lorem-ipsum/index.html")
59
+ assert_equal path, post.write_path
60
+ end
61
+
62
+ should "be sortable" do
63
+
64
+ end
65
+
66
+ end
67
+ end