laze 0.2.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/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +150 -0
- data/Rakefile +76 -0
- data/VERSION.yml +5 -0
- data/bin/laze +126 -0
- data/examples/website/includes/tagline.html +1 -0
- data/examples/website/input/contact/email.md +6 -0
- data/examples/website/input/css/screen.css +5 -0
- data/examples/website/input/css/test.less +6 -0
- data/examples/website/input/img/ruby.gif +0 -0
- data/examples/website/input/img/test.jpg +0 -0
- data/examples/website/input/img/test.png +0 -0
- data/examples/website/input/index.md +13 -0
- data/examples/website/input/js/foo.js +1 -0
- data/examples/website/input/js/lib.js +5 -0
- data/examples/website/layouts/default.html +15 -0
- data/examples/website/layouts/subpage.html +5 -0
- data/examples/website/laze.yml +1 -0
- data/features/create_sites.feature +73 -0
- data/features/plugins.feature +49 -0
- data/features/site_data.feature +26 -0
- data/features/step_definitions/laze_steps.rb +77 -0
- data/features/support/env.rb +17 -0
- data/lib/laze.rb +64 -0
- data/lib/laze/asset.rb +7 -0
- data/lib/laze/core_extensions.rb +15 -0
- data/lib/laze/item.rb +59 -0
- data/lib/laze/javascript.rb +5 -0
- data/lib/laze/layout.rb +105 -0
- data/lib/laze/page.rb +33 -0
- data/lib/laze/plugins.rb +56 -0
- data/lib/laze/plugins/cache_buster.rb +49 -0
- data/lib/laze/plugins/css_imports.rb +42 -0
- data/lib/laze/plugins/cssmin.rb +31 -0
- data/lib/laze/plugins/image_check.rb +28 -0
- data/lib/laze/plugins/image_optimizer.rb +52 -0
- data/lib/laze/plugins/js_requires.rb +63 -0
- data/lib/laze/plugins/jsmin.rb +31 -0
- data/lib/laze/plugins/less.rb +35 -0
- data/lib/laze/plugins/robots.rb +28 -0
- data/lib/laze/plugins/sitemap.rb +63 -0
- data/lib/laze/renderer.rb +47 -0
- data/lib/laze/renderers/javascript_renderer.rb +16 -0
- data/lib/laze/renderers/page_renderer.rb +40 -0
- data/lib/laze/renderers/stylesheet_renderer.rb +16 -0
- data/lib/laze/secretary.rb +74 -0
- data/lib/laze/section.rb +39 -0
- data/lib/laze/store.rb +51 -0
- data/lib/laze/stores/filesystem.rb +127 -0
- data/lib/laze/stylesheet.rb +6 -0
- data/lib/laze/target.rb +56 -0
- data/lib/laze/targets/filesystem.rb +41 -0
- data/test/helper.rb +12 -0
- data/test/test_assets.rb +28 -0
- data/test/test_core_extensions.rb +19 -0
- data/test/test_item.rb +59 -0
- data/test/test_layout.rb +47 -0
- data/test/test_renderer.rb +71 -0
- data/test/test_renderers.rb +40 -0
- data/test/test_secretary.rb +48 -0
- data/test/test_store.rb +18 -0
- data/test/test_target.rb +84 -0
- metadata +207 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
title: welcome
|
2
|
+
layout: default
|
3
|
+
---
|
4
|
+
Welcome to our awesome websites!
|
5
|
+
{% include 'tagline' %}
|
6
|
+
|
7
|
+
## Lorem ipsum dolor sit amet...
|
8
|
+
|
9
|
+
...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.
|
10
|
+
|
11
|
+
### The title of this page is {{ page.title }}
|
12
|
+
|
13
|
+
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.
|
@@ -0,0 +1 @@
|
|
1
|
+
var hello = 'Welcome to this awesome page.';
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>{{ page.title }} – Laze demo</title>
|
5
|
+
<link rel="stylesheet" href="css/screen.css" media="screen" charset="utf-8">
|
6
|
+
<script src="js/lib.js"></script>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<h1>Laze demonstration website</h1>
|
10
|
+
<hr>
|
11
|
+
{{ yield }}
|
12
|
+
<hr>
|
13
|
+
<p>Generated with Laze, the static site generator</p>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
domain: http://example.com
|
@@ -0,0 +1,73 @@
|
|
1
|
+
Feature: Create sites
|
2
|
+
As a web developer
|
3
|
+
I want to be able to make a static website
|
4
|
+
In order to earn a living
|
5
|
+
|
6
|
+
Scenario: Basic site
|
7
|
+
Given I have an 'input/index.html' file that contains 'basic site'
|
8
|
+
When I run laze
|
9
|
+
Then the output directory should exist
|
10
|
+
And I should see 'basic site' in 'output/index.html'
|
11
|
+
|
12
|
+
Scenario: Site with directories
|
13
|
+
Given I have an 'input/contact/index.html' file that contains 'contact!'
|
14
|
+
When I run laze
|
15
|
+
Then the output directory should exist
|
16
|
+
And I should see 'contact!' in 'output/contact/index.html'
|
17
|
+
|
18
|
+
Scenario: Basic site with a layout
|
19
|
+
Given I have a layouts directory
|
20
|
+
And I have an 'input/index.html' page with layout 'default' that contains 'page with layout'
|
21
|
+
And I have a 'default' layout that contains 'Layout: {{ yield }}'
|
22
|
+
When I run laze
|
23
|
+
Then the output directory should exist
|
24
|
+
And I should see 'Layout: <p>page with layout</p>' in 'output/index.html'
|
25
|
+
|
26
|
+
Scenario: Basic site with nested layouts
|
27
|
+
Given I have a layouts directory
|
28
|
+
And I have an 'input/index.html' page with layout 'post' that contains 'page'
|
29
|
+
And I have a 'post' layout with layout 'default' that contains 'Post: {{ yield }}'
|
30
|
+
And I have a 'default' layout that contains 'Layout: {{ yield }}'
|
31
|
+
When I run laze
|
32
|
+
Then the output directory should exist
|
33
|
+
And I should see 'Layout: Post: <p>page</p>' in 'output/index.html'
|
34
|
+
|
35
|
+
Scenario: Basic site with includes
|
36
|
+
Given I have a includes directory
|
37
|
+
And I have an 'input/index.html' file that contains "Included: {% include 'foo' %}"
|
38
|
+
And I have an 'includes/foo.html' file that contains 'foo'
|
39
|
+
When I run laze
|
40
|
+
Then the output directory should exist
|
41
|
+
And I should see 'Included: foo' in 'output/index.html'
|
42
|
+
|
43
|
+
Scenario: CSS files
|
44
|
+
Given I have an 'input/base.css' file that contains 'foo'
|
45
|
+
When I run laze
|
46
|
+
Then the output directory should exist
|
47
|
+
And I should see 'foo' in 'output/base.css'
|
48
|
+
|
49
|
+
Scenario: LESS files
|
50
|
+
Given I have an 'input/base.less' file that contains '#foo { width: 1+1; }'
|
51
|
+
When I run laze
|
52
|
+
Then the output directory should exist
|
53
|
+
And I should see '#foo \{ width: 2; \}' in 'output/base.css'
|
54
|
+
|
55
|
+
Scenario: Javascript files
|
56
|
+
Given I have an 'input/base.js' file that contains 'foo'
|
57
|
+
When I run laze
|
58
|
+
Then the output directory should exist
|
59
|
+
And I should see 'foo' in 'output/base.js'
|
60
|
+
|
61
|
+
Scenario: XML Sitemaps
|
62
|
+
Given I have an 'input/test.html' file that contains 'foo'
|
63
|
+
When I run laze
|
64
|
+
Then the output directory should exist
|
65
|
+
And I should see 'foo' in 'output/test.html'
|
66
|
+
And I should see 'test.html' in 'output/sitemap.xml'
|
67
|
+
|
68
|
+
Scenario: robots.txt
|
69
|
+
Given I have an 'input/test.html' file that contains 'foo'
|
70
|
+
When I run laze
|
71
|
+
Then the output directory should exist
|
72
|
+
And I should see 'foo' in 'output/test.html'
|
73
|
+
And I should see 'Sitemap: sitemap.xml' in 'output/robots.txt'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
@plugins
|
2
|
+
Feature: Plugins
|
3
|
+
In order to automate tasks
|
4
|
+
As a web developer
|
5
|
+
I want to use plugins to awesomize my website
|
6
|
+
|
7
|
+
Scenario: CSS compression
|
8
|
+
Given I have an 'input/screen.css' file that contains
|
9
|
+
"""
|
10
|
+
a {
|
11
|
+
color: #000;
|
12
|
+
}
|
13
|
+
|
14
|
+
"""
|
15
|
+
When I run laze with minification
|
16
|
+
Then the output directory should exist
|
17
|
+
And I should see 'a\{color:#000;\}' in 'output/screen.css'
|
18
|
+
|
19
|
+
Scenario: Javascript compression
|
20
|
+
Given I have an 'input/base.js' file that contains
|
21
|
+
"""
|
22
|
+
var hello = "world";
|
23
|
+
|
24
|
+
"""
|
25
|
+
When I run laze with minification
|
26
|
+
Then the output directory should exist
|
27
|
+
And I should see 'var hello="world";' in 'output/base.js'
|
28
|
+
|
29
|
+
|
30
|
+
Scenario: Javascript requires
|
31
|
+
Given I have an 'input/base.js' file that contains '// require "foo.js"'
|
32
|
+
And I have an 'input/foo.js' file that contains '// test'
|
33
|
+
When I run laze
|
34
|
+
Then the output directory should exist
|
35
|
+
And I should see '// test' in 'output/base.js'
|
36
|
+
|
37
|
+
Scenario: CSS imports
|
38
|
+
Given I have an 'input/base.css' file that contains '@import url(bar.css)'
|
39
|
+
And I have an 'input/bar.css' file that contains 'baaah'
|
40
|
+
When I run laze
|
41
|
+
Then the output directory should exist
|
42
|
+
And I should see 'baaah' in 'output/base.css'
|
43
|
+
|
44
|
+
Scenario: CSS cache busters
|
45
|
+
Given I have an 'input/base.css' file that contains 'foo { background: url(test.png); }'
|
46
|
+
And I have an 'input/test.png' file that contains 'foo'
|
47
|
+
When I run laze
|
48
|
+
Then the output directory should exist
|
49
|
+
And I should see 'url\(test.png\?\d+\)' in 'output/base.css'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: Site data
|
2
|
+
As a web designer creating a static website
|
3
|
+
I want to be able to embed data into my site
|
4
|
+
In order to speed up development
|
5
|
+
|
6
|
+
Scenario: use page variable in a page
|
7
|
+
Given I have an 'input/index.html' page with title 'Foo' that contains '{{ page.title }}'
|
8
|
+
When I run laze
|
9
|
+
Then the output directory should exist
|
10
|
+
And I should see 'Foo' in 'output/index.html'
|
11
|
+
|
12
|
+
Scenario: use variables in a layout
|
13
|
+
Given I have a layouts directory
|
14
|
+
And I have a 'default' layout that contains '{{ page.title }}: {{ yield }}'
|
15
|
+
And I have an 'input/index.html' page with title 'Foo' and with layout 'default' that contains 'bar'
|
16
|
+
When I run laze
|
17
|
+
Then the output directory should exist
|
18
|
+
And I should see 'Foo: <p>bar</p>' in 'output/index.html'
|
19
|
+
|
20
|
+
Scenario: use variables in an include
|
21
|
+
Given I have a includes directory
|
22
|
+
And I have an 'includes/foo.html' file that contains '{{ page.title }}'
|
23
|
+
And I have an 'input/index.html' page with title 'Foo' that contains '{% include \'foo\' %}'
|
24
|
+
When I run laze
|
25
|
+
Then the output directory should exist
|
26
|
+
And I should see 'Foo' in 'output/index.html'
|
@@ -0,0 +1,77 @@
|
|
1
|
+
Before do
|
2
|
+
FileUtils.mkdir(TEST_DIR)
|
3
|
+
Dir.chdir(TEST_DIR)
|
4
|
+
end
|
5
|
+
|
6
|
+
After do
|
7
|
+
Dir.chdir(TEST_DIR)
|
8
|
+
FileUtils.rm_rf(TEST_DIR) if File.directory?(TEST_DIR)
|
9
|
+
end
|
10
|
+
|
11
|
+
Given /^I have an '(.+?)' file that contains ('|")(.*)\2$/ do |file, quote, text|
|
12
|
+
FileUtils.mkdir_p(File.dirname(file))
|
13
|
+
File.open(file, 'w') do |f|
|
14
|
+
f.write(text)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Given /^I have a (.+?) directory$/ do |dir|
|
19
|
+
FileUtils.mkdir(dir)
|
20
|
+
end
|
21
|
+
|
22
|
+
Given /^I have a '(.+?)' layout that contains ('|")(.*)\2$/ do |layout, quote, text|
|
23
|
+
File.open(File.join('layouts', layout + '.html'), 'w') do |f|
|
24
|
+
f.write(text)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Given /^I have a '(.+?)' layout with layout '(.+?)' that contains '(.*)'$/ do |filename, layout, text|
|
29
|
+
File.open(File.join('layouts', filename + '.html'), 'w') do |f|
|
30
|
+
f.write <<-EOF
|
31
|
+
layout: #{layout}
|
32
|
+
---
|
33
|
+
#{text}
|
34
|
+
EOF
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Given /^I have a '(.+?)' file that contains '(.*)'$/ do |file, text|
|
39
|
+
File.open(file, 'w') do |f|
|
40
|
+
f.write(text)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Given /^I have an? '(.+?)' file that contains$/ do |file, text|
|
45
|
+
FileUtils.mkdir_p(File.dirname(file))
|
46
|
+
File.open(file, 'w') do |f|
|
47
|
+
f.write(text)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Given /^I have an '(.*?)' page(?: with (.*?) '(.*?)')?(?: and with (.*?) '(.*?)')? that contains '(.*)'$/ do |file, key, value, other_key, other_value, text|
|
52
|
+
FileUtils.mkdir('input') unless File.directory?('input')
|
53
|
+
File.open(file, 'w') do |f|
|
54
|
+
f.write <<EOF
|
55
|
+
#{key}: #{value}
|
56
|
+
#{other_key + ': ' + other_value unless other_key.nil?}
|
57
|
+
---
|
58
|
+
#{text}
|
59
|
+
EOF
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
When /^I run laze$/ do
|
64
|
+
run_laze
|
65
|
+
end
|
66
|
+
|
67
|
+
When /^I run laze with minification$/ do
|
68
|
+
run_laze(:minify => true)
|
69
|
+
end
|
70
|
+
|
71
|
+
Then /^the (.+?) directory should exist$/ do |dir|
|
72
|
+
assert File.directory?(dir)
|
73
|
+
end
|
74
|
+
|
75
|
+
Then /^I should see '(.*)' in '(.+?)'$/ do |text, file|
|
76
|
+
assert_match Regexp.new(text), File.open(file).readlines.join
|
77
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rr'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
World do
|
6
|
+
include Test::Unit::Assertions
|
7
|
+
end
|
8
|
+
|
9
|
+
TEST_DIR = File.join(ENV['PWD'], 'tmp')
|
10
|
+
LAZE_PATH = File.join(ENV['PWD'], 'bin', 'laze')
|
11
|
+
|
12
|
+
def run_laze(options = {})
|
13
|
+
command = LAZE_PATH.dup
|
14
|
+
command << ' -m' if options[:minify]
|
15
|
+
command << ' >> /dev/null 2>&1' if options[:debug].nil?
|
16
|
+
system command
|
17
|
+
end
|
data/lib/laze.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
2
|
+
|
3
|
+
begin
|
4
|
+
# Core
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
# Standard library
|
8
|
+
require 'fileutils'
|
9
|
+
require 'logger'
|
10
|
+
|
11
|
+
# Third party
|
12
|
+
require 'liquid'
|
13
|
+
require 'rdiscount'
|
14
|
+
require 'redcloth'
|
15
|
+
rescue LoadError
|
16
|
+
# Gems
|
17
|
+
retry if require 'rubygems'
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
|
21
|
+
module Laze #:nodoc:
|
22
|
+
def debug(msg)
|
23
|
+
LOGGER.debug(msg) if const_defined?('LOGGER')
|
24
|
+
end
|
25
|
+
|
26
|
+
def warn(msg)
|
27
|
+
LOGGER.warn(msg) if const_defined?('LOGGER')
|
28
|
+
end
|
29
|
+
|
30
|
+
def info(msg)
|
31
|
+
LOGGER.info(msg) if const_defined?('LOGGER')
|
32
|
+
end
|
33
|
+
|
34
|
+
def fatal(msg)
|
35
|
+
LOGGER.fatal(msg) if const_defined?('LOGGER')
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.version
|
39
|
+
yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
|
40
|
+
"#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
|
41
|
+
end
|
42
|
+
|
43
|
+
extend self
|
44
|
+
end
|
45
|
+
|
46
|
+
# Internal requires
|
47
|
+
require 'laze/core_extensions'
|
48
|
+
require 'laze/plugins'
|
49
|
+
require 'laze/item'
|
50
|
+
require 'laze/page'
|
51
|
+
require 'laze/asset'
|
52
|
+
require 'laze/stylesheet'
|
53
|
+
require 'laze/javascript'
|
54
|
+
require 'laze/renderer'
|
55
|
+
require 'laze/renderers/page_renderer'
|
56
|
+
require 'laze/renderers/stylesheet_renderer'
|
57
|
+
require 'laze/renderers/javascript_renderer'
|
58
|
+
require 'laze/section'
|
59
|
+
require 'laze/layout'
|
60
|
+
require 'laze/secretary'
|
61
|
+
require 'laze/target'
|
62
|
+
require 'laze/targets/filesystem'
|
63
|
+
require 'laze/store'
|
64
|
+
require 'laze/stores/filesystem'
|
data/lib/laze/asset.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Hash #:nodoc:
|
2
|
+
def stringify_keys
|
3
|
+
inject({}) do |output, (key, value)|
|
4
|
+
output[(key.to_s rescue key) || key] = value
|
5
|
+
output
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def symbolize_keys
|
10
|
+
inject({}) do |output, (key, value)|
|
11
|
+
output[(key.to_sym rescue key) || key] = value
|
12
|
+
output
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/laze/item.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Laze
|
2
|
+
# An item is a basic node in a site. It is usually not used directly, but
|
3
|
+
# only through one of its subclasses, like Page or Section. An item is used
|
4
|
+
# as a generic container for static files, such as images.
|
5
|
+
class Item
|
6
|
+
# Hash of proprties, like page title or output filename.
|
7
|
+
attr_accessor :properties
|
8
|
+
|
9
|
+
# Other item that has this item as one of its subitems.
|
10
|
+
attr_accessor :parent
|
11
|
+
|
12
|
+
# Contents of the file
|
13
|
+
attr_accessor :content
|
14
|
+
|
15
|
+
# New items should be created with a hash of options:
|
16
|
+
#
|
17
|
+
# Item.new :title => 'Foo'
|
18
|
+
#
|
19
|
+
def initialize(properties, content)
|
20
|
+
@properties, @content, @parent = properties, content, nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# Test if this item has a given property.
|
24
|
+
def has?(key)
|
25
|
+
@properties.has_key?(key)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Shortcut method to the filename property.
|
29
|
+
def filename
|
30
|
+
@properties[:filename]
|
31
|
+
end
|
32
|
+
|
33
|
+
def number_of_subitems
|
34
|
+
0
|
35
|
+
end
|
36
|
+
|
37
|
+
# An array of items, where each item is the next's
|
38
|
+
# parent.
|
39
|
+
def ancestors
|
40
|
+
parent ? [parent, *parent.ancestors].reverse : []
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s #:nodoc:
|
44
|
+
filename
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect #:nodoc:
|
48
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)} #{filename}>"
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def self.include_plugins(kind) #:nodoc:
|
54
|
+
Laze::Plugins.each do |plugin|
|
55
|
+
include plugin if plugin.applies_to?(kind)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|