stack 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/VERSION.yml +1 -1
- data/lib/stack/generator.rb +55 -4
- data/lib/stack/parsable.rb +48 -0
- data/lib/stack/runner.rb +3 -1
- data/lib/stack/template.rb +95 -0
- data/lib/stack/templates/layout.rb +18 -0
- data/lib/stack/templates/page.rb +14 -0
- data/lib/stack.rb +16 -1
- metadata +16 -2
data/Rakefile
CHANGED
@@ -12,6 +12,7 @@ begin
|
|
12
12
|
gem.authors = ["sixones"]
|
13
13
|
gem.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
|
14
14
|
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
15
|
+
gem.add_dependency "liquid", ">= 1.9.0"
|
15
16
|
|
16
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
18
|
end
|
data/VERSION.yml
CHANGED
data/lib/stack/generator.rb
CHANGED
@@ -1,16 +1,67 @@
|
|
1
1
|
module Stack
|
2
2
|
class Generator
|
3
|
+
attr_accessor :layouts
|
4
|
+
attr_accessor :pages
|
5
|
+
|
3
6
|
def initialize
|
4
|
-
puts "Source -> #{Stack::runner.configuration.source}"
|
5
|
-
|
6
7
|
# read layouts
|
7
|
-
# read "objects"
|
8
8
|
# read pages
|
9
9
|
# write pages
|
10
|
+
|
11
|
+
process!
|
12
|
+
end
|
13
|
+
|
14
|
+
def process!
|
15
|
+
read_layouts
|
16
|
+
read_pages
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_layouts
|
20
|
+
@layouts = read_pages_from_directory("_layouts", Stack::Templates::Layout)
|
10
21
|
end
|
11
22
|
|
12
|
-
def
|
23
|
+
def read_pages
|
24
|
+
@pages = read_pages_from_directory(Stack::runner.configuration.source, Stack::Templates::Page)
|
25
|
+
end
|
26
|
+
|
27
|
+
def transform!
|
28
|
+
puts @layouts
|
29
|
+
puts @pages
|
30
|
+
|
31
|
+
self.pages.each do |name, page|
|
32
|
+
puts "Page -> #{name} #{page}"
|
33
|
+
page.write!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
{
|
39
|
+
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def read_pages_from_directory(folder, transformable_klass)
|
45
|
+
pages = { }
|
46
|
+
|
47
|
+
begin
|
48
|
+
path = (folder == Stack::runner.configuration.source) ? folder : File.join(Stack::runner.configuration.source, folder)
|
49
|
+
entries = Dir.entries(path)
|
50
|
+
|
51
|
+
files = entries.reject { |e| File.directory?(File.join(path, e)) }
|
52
|
+
files = files.reject { |e| e[0..0]=~/\.|_/ or e[-1..-1]=="~" }
|
53
|
+
files = files.select { |e| Stack::EXTENSIONS.include?(File.extname(e)) }
|
54
|
+
|
55
|
+
files.each do |f|
|
56
|
+
trans = transformable_klass.new(File.join(path, f), self)
|
57
|
+
pages[f.split(".").first] = trans
|
58
|
+
end
|
59
|
+
rescue Errno::ENOENT => e
|
60
|
+
# Ignore
|
61
|
+
puts e.to_str
|
62
|
+
end
|
13
63
|
|
64
|
+
return pages
|
14
65
|
end
|
15
66
|
end
|
16
67
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Stack
|
2
|
+
module Parsable
|
3
|
+
attr_accessor :raw
|
4
|
+
attr_accessor :data
|
5
|
+
attr_accessor :inline_data
|
6
|
+
|
7
|
+
def parse!(raw_doc = self.raw, defaults = { })
|
8
|
+
self.data, self.raw = extract_yaml(raw_doc, nil, defaults)
|
9
|
+
|
10
|
+
puts self.data
|
11
|
+
end
|
12
|
+
|
13
|
+
def payload
|
14
|
+
self.data.deep_symbolize.merge(:inline_data => inline_data)
|
15
|
+
end
|
16
|
+
|
17
|
+
def extract_yaml(raw, replace = nil, defaults = { })
|
18
|
+
self.inline_data = [ ]
|
19
|
+
|
20
|
+
data_table = defaults
|
21
|
+
out = raw.dup
|
22
|
+
i = -1
|
23
|
+
|
24
|
+
puts "out -> #{out}"
|
25
|
+
|
26
|
+
while out =~ /^(---\s*\n.*?\n?)(---.*?\n)/m
|
27
|
+
yaml = $1.dup
|
28
|
+
out = out.gsub(/#{Regexp.escape(yaml)}#{Regexp.escape($2)}/m,((i>-1) ? "{{ document.inline_data[#{i}] | render_table }}" : ""))
|
29
|
+
|
30
|
+
puts "out2 -> #{out}"
|
31
|
+
|
32
|
+
d = YAML.load(yaml)
|
33
|
+
|
34
|
+
if d.is_a?(Hash)
|
35
|
+
self.inline_data << d if i > -1
|
36
|
+
data_table = data_table.deep_merge(d)
|
37
|
+
end
|
38
|
+
|
39
|
+
d = nil;
|
40
|
+
i += 1;
|
41
|
+
end
|
42
|
+
|
43
|
+
data_table = data_table.deep_symbolize
|
44
|
+
|
45
|
+
return data_table, out
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/stack/runner.rb
CHANGED
@@ -3,6 +3,7 @@ module Stack
|
|
3
3
|
attr_accessor :configuration
|
4
4
|
attr_accessor :command
|
5
5
|
attr_accessor :arguments
|
6
|
+
attr_accessor :generator
|
6
7
|
|
7
8
|
def initialize(argv)
|
8
9
|
@argv = argv
|
@@ -36,7 +37,8 @@ module Stack
|
|
36
37
|
|
37
38
|
# Runs the specified command
|
38
39
|
def run_command
|
39
|
-
Stack::Generator.new
|
40
|
+
@generator = Stack::Generator.new
|
41
|
+
@generator.transform!
|
40
42
|
end
|
41
43
|
end
|
42
44
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Stack
|
2
|
+
module Template
|
3
|
+
attr_accessor :generator
|
4
|
+
|
5
|
+
attr_accessor :basename
|
6
|
+
attr_accessor :path
|
7
|
+
|
8
|
+
attr_accessor :raw
|
9
|
+
|
10
|
+
def initialize(path, generator = nil)
|
11
|
+
self.generator = generator
|
12
|
+
self.path = path
|
13
|
+
|
14
|
+
if File.file?(path)
|
15
|
+
self.basename = File.basename(path)
|
16
|
+
|
17
|
+
read
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def read
|
22
|
+
f = File.open(self.path)
|
23
|
+
self.raw = f.read
|
24
|
+
f.close
|
25
|
+
end
|
26
|
+
|
27
|
+
def render(_payload = { }, do_layout = true)
|
28
|
+
_payload = template_payload.deep_merge(_payload)
|
29
|
+
|
30
|
+
content = Liquid::Template.parse(self.raw).render(_payload)
|
31
|
+
content = self.transform(content)
|
32
|
+
|
33
|
+
if (layout_name = _payload[:layout]) and (do_layout)
|
34
|
+
_payload.delete(:layout)
|
35
|
+
begin
|
36
|
+
_payload = _payload.deep_merge({ "content" => content })
|
37
|
+
puts _payload
|
38
|
+
content = self.generator.layouts[layout_name].render(_payload)
|
39
|
+
rescue => e
|
40
|
+
STDERR.puts e.to_str
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
return content
|
45
|
+
end
|
46
|
+
|
47
|
+
def template_payload
|
48
|
+
{
|
49
|
+
:generator => self.generator.to_hash
|
50
|
+
}.merge(self.payload)
|
51
|
+
end
|
52
|
+
|
53
|
+
def payload
|
54
|
+
raise InterfaceNotProvided
|
55
|
+
end
|
56
|
+
|
57
|
+
def transform(content = self.raw)
|
58
|
+
case self.basename
|
59
|
+
when /\.textile/
|
60
|
+
RedCloth.new(content).to_html
|
61
|
+
when /\.(mdown|markdown)/
|
62
|
+
Maruku.new(content).to_html
|
63
|
+
else
|
64
|
+
content
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def write!(content = self.render)
|
69
|
+
puts write_path
|
70
|
+
|
71
|
+
FileUtils.mkdir_p(File.dirname(write_path))
|
72
|
+
out = File.open(write_path, "w+")
|
73
|
+
out.rewind
|
74
|
+
out.write(content)
|
75
|
+
out.close
|
76
|
+
end
|
77
|
+
|
78
|
+
def write_path
|
79
|
+
File.join(Stack::runner.configuration.target, self.write_filename)
|
80
|
+
end
|
81
|
+
|
82
|
+
def write_basename
|
83
|
+
if basename
|
84
|
+
ext = File.extname(basename)
|
85
|
+
basename[0..(basename.length - ext.length - 1)]
|
86
|
+
else
|
87
|
+
@write_basename ||= Digest::MD5.hexdigest(self.raw)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def write_filename
|
92
|
+
"#{write_basename}.html"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/stack.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# rubygems
|
2
2
|
require 'rubygems'
|
3
3
|
require 'optparse'
|
4
|
+
require 'liquid'
|
4
5
|
|
5
6
|
require 'core_ext/hash'
|
6
7
|
|
@@ -8,6 +9,12 @@ require 'stack/configuration'
|
|
8
9
|
require 'stack/generator'
|
9
10
|
require 'stack/runner'
|
10
11
|
|
12
|
+
require 'stack/template'
|
13
|
+
require 'stack/parsable'
|
14
|
+
|
15
|
+
require 'stack/templates/page'
|
16
|
+
require 'stack/templates/layout'
|
17
|
+
|
11
18
|
module Stack
|
12
19
|
# Default options used by stack, overridden from the command line or YML configration file.
|
13
20
|
DEFAULTS = {
|
@@ -18,6 +25,9 @@ module Stack
|
|
18
25
|
# Array of valid commands stack can use
|
19
26
|
COMMANDS = %w(create generate server)
|
20
27
|
|
28
|
+
# Array of valid extensions
|
29
|
+
EXTENSIONS = %w(.html .markdown .mdown)
|
30
|
+
|
21
31
|
class << self
|
22
32
|
attr_accessor :runner
|
23
33
|
end
|
@@ -29,7 +39,12 @@ module Stack
|
|
29
39
|
parser = OptionParser.new do |opts|
|
30
40
|
opts.banner = "Usage: stack [options] #{Stack::COMMANDS.join('|')}"
|
31
41
|
|
32
|
-
opts.on("-s", "--source [DIR]", "Directory to use as the source for generating a stack") do |l|
|
42
|
+
opts.on("-s", "--source [DIR]", "Directory to use as the source for generating a stack") do |l|
|
43
|
+
if !l.nil?
|
44
|
+
config[:source] = l
|
45
|
+
config[:target] = "#{config[:source]}_stack"
|
46
|
+
end
|
47
|
+
end
|
33
48
|
opts.on("-t", "--target [DIR]", "Directory to use as the target directory") do |l| config[:target] = l unless l.nil? end
|
34
49
|
|
35
50
|
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sixones
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-31 00:00:00 +00:00
|
13
13
|
default_executable: stack
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: liquid
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.9.0
|
34
|
+
version:
|
25
35
|
description: Generates a static site from template files in Liquid, Markdown and Textile.
|
26
36
|
email: dev@sixones.com
|
27
37
|
executables:
|
@@ -41,7 +51,11 @@ files:
|
|
41
51
|
- lib/stack.rb
|
42
52
|
- lib/stack/configuration.rb
|
43
53
|
- lib/stack/generator.rb
|
54
|
+
- lib/stack/parsable.rb
|
44
55
|
- lib/stack/runner.rb
|
56
|
+
- lib/stack/template.rb
|
57
|
+
- lib/stack/templates/layout.rb
|
58
|
+
- lib/stack/templates/page.rb
|
45
59
|
- test/helper.rb
|
46
60
|
- test/test_stack.rb
|
47
61
|
has_rdoc: true
|