ace 0.1
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 +3 -0
- data/CHANGELOG +3 -0
- data/LICENSE +20 -0
- data/README.textile +18 -0
- data/TODO +1 -0
- data/ace.gemspec +53 -0
- data/ace.pre.gemspec +6 -0
- data/bin/ace +76 -0
- data/bin/ace-gen +32 -0
- data/example/app/posts.rb +20 -0
- data/example/app/tags.rb +28 -0
- data/example/boot.rb +6 -0
- data/example/config.yml +2 -0
- data/example/content/assets/css/style.css +1 -0
- data/example/content/assets/js/application.js +3 -0
- data/example/content/index.html.haml +5 -0
- data/example/content/posts.json.rb +0 -0
- data/example/content/posts/node-js.html +29 -0
- data/example/content/posts/ruby.html +21 -0
- data/example/layouts/base.html.haml +5 -0
- data/example/layouts/post.html.haml +5 -0
- data/example/layouts/tag.html.haml +6 -0
- data/example/lib/initializer.rb +0 -0
- data/example/output/assets/css/style.css +1 -0
- data/example/output/assets/js/application.js +3 -0
- data/example/output/posts/node-js.html +32 -0
- data/example/output/posts/ruby.html +24 -0
- data/example/output/posts/test.html +10 -0
- data/example/output/tags/development.html +11 -0
- data/example/output/tags/javascript.html +10 -0
- data/example/output/tags/node.js.html +10 -0
- data/example/output/tags/ruby.html +10 -0
- data/example/rules.rb +8 -0
- data/example/tasks.rb +0 -0
- data/lib/ace.rb +140 -0
- data/lib/ace/dsl.rb +21 -0
- data/lib/ace/filters.rb +9 -0
- data/lib/ace/filters/haml.rb +19 -0
- data/lib/ace/filters/layout.rb +22 -0
- data/lib/ace/filters/template.rb +25 -0
- data/lib/ace/version.rb +5 -0
- data/project_generator/metadata.yml +3 -0
- data/project_generator/postprocess.rb +9 -0
- data/project_generator/setup.rb +9 -0
- data/simple-templater.scope +6 -0
- metadata +137 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jakub Šťastný aka Botanicus
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
h1. Why you should be interested in ace?
|
2
|
+
|
3
|
+
In Ace, every page is an instance
|
4
|
+
Typically I want to define methods, like @post.excerpt
|
5
|
+
|
6
|
+
There are also *generators* available for easier generating items on the fly.
|
7
|
+
|
8
|
+
Ace has *template inheritance*. I love template inheritance, it's more flexible pattern than layouts.
|
9
|
+
|
10
|
+
Tasks for deployment included.
|
11
|
+
|
12
|
+
h1. The boot process
|
13
|
+
|
14
|
+
# load @boot.rb@ where the
|
15
|
+
# load the rules (controllers / globs mapping)
|
16
|
+
# load & instantiate the items: only the renderables (concrete post)
|
17
|
+
# run the filters, layoutin' ... actually this can be defined in the controller
|
18
|
+
# match the routes, write the files
|
data/ace.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "base64"
|
5
|
+
require File.expand_path("../lib/ace/version", __FILE__)
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "ace"
|
9
|
+
s.version = Ace::VERSION
|
10
|
+
s.authors = ["Jakub Šťastný aka Botanicus"]
|
11
|
+
s.homepage = "http://github.com/botanicus/ace"
|
12
|
+
s.summary = "Ace is highly flexible static pages generator with template inheritance."
|
13
|
+
s.description = "" # TODO: long description
|
14
|
+
s.cert_chain = nil
|
15
|
+
s.email = Base64.decode64("c3Rhc3RueUAxMDFpZGVhcy5jeg==\n")
|
16
|
+
s.has_rdoc = true
|
17
|
+
|
18
|
+
# files
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
|
21
|
+
s.executables = Dir["bin/*"].map(&File.method(:basename))
|
22
|
+
s.default_executable = "ace"
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
# Ruby version
|
26
|
+
# Current JRuby with --1.9 switch has RUBY_VERSION set to "1.9.2dev"
|
27
|
+
# and RubyGems don't play well with it, so we have to set minimal
|
28
|
+
# Ruby version to 1.9, even if it actually is 1.9.1
|
29
|
+
s.required_ruby_version = ::Gem::Requirement.new("~> 1.9")
|
30
|
+
|
31
|
+
# Dependencies
|
32
|
+
# RubyGems has runtime dependencies (add_dependency) and
|
33
|
+
# development dependencies (add_development_dependency)
|
34
|
+
# Ace isn't a monolithic framework, so you might want
|
35
|
+
# to use just one specific part of it, so it has no sense
|
36
|
+
# to specify dependencies for the whole gem. If you want
|
37
|
+
# to install everything what you need for start with Ace,
|
38
|
+
# just run gem install ace --development
|
39
|
+
|
40
|
+
s.add_dependency "template-inheritance"
|
41
|
+
s.add_development_dependency "simple-templater", ">= 0.0.1.2"
|
42
|
+
|
43
|
+
begin
|
44
|
+
require "changelog"
|
45
|
+
rescue LoadError
|
46
|
+
warn "You have to have changelog gem installed for post install message"
|
47
|
+
else
|
48
|
+
s.post_install_message = CHANGELOG.new.version_changes
|
49
|
+
end
|
50
|
+
|
51
|
+
# RubyForge
|
52
|
+
s.rubyforge_project = "ace"
|
53
|
+
end
|
data/ace.pre.gemspec
ADDED
data/bin/ace
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
if RUBY_VERSION < "1.9.1"
|
5
|
+
abort "Ace requires Ruby 1.9."
|
6
|
+
end
|
7
|
+
|
8
|
+
base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
9
|
+
libdir = File.expand_path(File.join(File.dirname(base), "..", "lib"))
|
10
|
+
|
11
|
+
# because of system installation, there is bin/../lib, but not bin/../lib/ace
|
12
|
+
if File.directory?(File.join(libdir, "ace"))
|
13
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
require "ace"
|
17
|
+
require "ace/dsl"
|
18
|
+
|
19
|
+
if File.join(Dir.pwd, "boot.rb")
|
20
|
+
require File.join(Dir.pwd, "boot.rb")
|
21
|
+
else
|
22
|
+
abort "No boot.rb!"
|
23
|
+
end
|
24
|
+
|
25
|
+
if File.join(Dir.pwd, "rules.rb")
|
26
|
+
path = File.join(Dir.pwd, "rules.rb")
|
27
|
+
code = File.read(path)
|
28
|
+
rules = Ace::DSL.new
|
29
|
+
begin
|
30
|
+
rules.instance_eval(code)
|
31
|
+
rescue Exception => exception
|
32
|
+
puts "Error in DSL: #{exception.message}"
|
33
|
+
puts exception.backtrace
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
else
|
37
|
+
abort "No rules.rb!"
|
38
|
+
end
|
39
|
+
|
40
|
+
rules.rules.each do |klass, files|
|
41
|
+
puts "#{klass} #{files.inspect}"
|
42
|
+
files.each do |file|
|
43
|
+
if File.binread(file).match(/^-{3,5}\s*$/)
|
44
|
+
raw_item = Ace::RawItem.new(file).tap(&:parse)
|
45
|
+
item = klass.create(raw_item.metadata, raw_item.content)
|
46
|
+
else
|
47
|
+
item = klass.create(Hash.new, File.read(file))
|
48
|
+
end
|
49
|
+
item.original_path = file
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
puts
|
54
|
+
|
55
|
+
rules.generators.each do |generator_klass|
|
56
|
+
puts "~ Running #{generator_klass}"
|
57
|
+
generator = generator_klass.new
|
58
|
+
begin
|
59
|
+
if generator.respond_to?(:run)
|
60
|
+
generator.run
|
61
|
+
else
|
62
|
+
abort "Generator #{generator.inspect} doesn't respond to the #run method!"
|
63
|
+
end
|
64
|
+
rescue Exception => exception
|
65
|
+
puts "Error in generator #{generator.inspect}: #{exception.message}"
|
66
|
+
puts exception.backtrace
|
67
|
+
exit 1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
puts
|
72
|
+
|
73
|
+
Ace::Item.all_instances.each do |item|
|
74
|
+
puts "~ Generating #{item.output_path}"
|
75
|
+
item.save!
|
76
|
+
end
|
data/bin/ace-gen
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
if RUBY_VERSION < "1.9.1"
|
5
|
+
abort "Ace requires Ruby 1.9."
|
6
|
+
end
|
7
|
+
|
8
|
+
base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
9
|
+
libdir = File.expand_path(File.join(File.dirname(base), "..", "lib"))
|
10
|
+
|
11
|
+
# because of system installation, there is bin/../lib, but not bin/../lib/ace
|
12
|
+
if File.directory?(File.join(libdir, "ace"))
|
13
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
require "simple-templater"
|
18
|
+
rescue LoadError
|
19
|
+
abort "You have to install simple-templater first!"
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
templater = SimpleTemplater.new(:ace)
|
24
|
+
generator = templater.find(:project)
|
25
|
+
generator.run(ARGV)
|
26
|
+
rescue SimpleTemplater::TargetAlreadyExist => exception
|
27
|
+
abort exception.message
|
28
|
+
rescue Interrupt
|
29
|
+
exit
|
30
|
+
rescue Exception => exception
|
31
|
+
abort "Exception #{exception.inspect} occured during running generator #{generator.inspect}\n#{exception.backtrace.join("\n")}"
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "nokogiri"
|
4
|
+
require "ace/filters"
|
5
|
+
|
6
|
+
# Inheritted methods:
|
7
|
+
# - content
|
8
|
+
# - metadata
|
9
|
+
# - config
|
10
|
+
class Post < Ace::Item
|
11
|
+
before Ace::LayoutFilter, layout: "post.html"
|
12
|
+
|
13
|
+
def document
|
14
|
+
Nokogiri::HTML(self.content)
|
15
|
+
end
|
16
|
+
|
17
|
+
def excerpt
|
18
|
+
self.document.css("p.excerpt")
|
19
|
+
end
|
20
|
+
end
|
data/example/app/tags.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Tag < Ace::Item
|
4
|
+
before Ace::LayoutFilter, layout: "tag.html"
|
5
|
+
end
|
6
|
+
|
7
|
+
class TagPagesGenerator
|
8
|
+
def tags
|
9
|
+
Post.instances.inject(Hash.new) do |buffer, post|
|
10
|
+
if tags = post.metadata[:tags]
|
11
|
+
tags.each do |tag|
|
12
|
+
buffer[tag] ||= Array.new
|
13
|
+
buffer[tag] << post
|
14
|
+
end
|
15
|
+
end
|
16
|
+
buffer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
self.tags.each do |tag_title, items|
|
22
|
+
tag_name = tag_title.downcase.gsub(" ", "-")
|
23
|
+
metadata = {title: tag_title, timestamp: Time.now}
|
24
|
+
tag = Tag.create(metadata, items)
|
25
|
+
tag.output_path = "output/tags/#{tag_name}.html"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/example/boot.rb
ADDED
data/example/config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
h1 { color: red; }
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
title: Node.js Asynchronous JavaScript Framework
|
3
|
+
timestamp: 2010-09-16
|
4
|
+
tags: ["Development", "JavaScript", "Node.js"]
|
5
|
+
---
|
6
|
+
|
7
|
+
<p class="excerpt">
|
8
|
+
Node.js is an evented I/O framework for the V8 JavaScript engine. It is intended for writing scalable network programs such as web servers.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Node.js is similar in purpose to Twisted for Python, Perl Object Environment for Perl, and EventMachine for Ruby. Unlike most JavaScript, it is not executed in a web browser, but it is rather related to server-side JavaScript. Node.js implements some CommonJS specifications[1]. Node.js includes a REPL environment for interactive testing.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
var sys = require('sys'),
|
17
|
+
http = require('http');
|
18
|
+
|
19
|
+
http.createServer(function (request, response) {
|
20
|
+
response.writeHead(200, {'Content-Type': 'text/plain'});
|
21
|
+
response.end('Hello World\n');
|
22
|
+
}).listen(8000);
|
23
|
+
|
24
|
+
sys.puts('Server running at http://127.0.0.1:8000/');
|
25
|
+
</pre>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Node.js">Wikipedia.org</em>.
|
29
|
+
</p>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
title: Ruby Programming Language
|
3
|
+
timestamp: 2010-09-14
|
4
|
+
tags: ["Development", "Ruby"]
|
5
|
+
---
|
6
|
+
|
7
|
+
<p class="excerpt">
|
8
|
+
Ruby is a dynamic, reflective, general purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto. It was influenced primarily by Perl, Smalltalk, Eiffel, and Lisp.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Ruby supports multiple programming paradigms, including functional, object oriented, imperative and reflective. It also has a dynamic type system and automatic memory management; it is therefore similar in varying respects to Python, Perl, Lisp, Dylan, Pike, and CLU.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
The standard 1.8.7 implementation is written in C, as a single-pass interpreted language. There is currently no specification of the Ruby language, so the original implementation is considered to be the de facto reference. As of 2010[update], there are a number of complete or upcoming alternative implementations of the Ruby language, including YARV, JRuby, Rubinius, IronRuby, MacRuby, and HotRuby, each of which takes a different approach, with IronRuby, JRuby and MacRuby providing just-in-time compilation and MacRuby also providing ahead-of-time compilation. The official 1.9 branch uses YARV, as will 2.0 (development), and will eventually supersede the slower Ruby MRI.
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<p>
|
20
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Wikipedia.org</em>.
|
21
|
+
</p>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
h1 { color: red; }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
<p class="excerpt">
|
8
|
+
Node.js is an evented I/O framework for the V8 JavaScript engine. It is intended for writing scalable network programs such as web servers.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Node.js is similar in purpose to Twisted for Python, Perl Object Environment for Perl, and EventMachine for Ruby. Unlike most JavaScript, it is not executed in a web browser, but it is rather related to server-side JavaScript. Node.js implements some CommonJS specifications[1]. Node.js includes a REPL environment for interactive testing.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
var sys = require('sys'),
|
17
|
+
http = require('http');
|
18
|
+
|
19
|
+
http.createServer(function (request, response) {
|
20
|
+
response.writeHead(200, {'Content-Type': 'text/plain'});
|
21
|
+
response.end('Hello World\n');
|
22
|
+
}).listen(8000);
|
23
|
+
|
24
|
+
sys.puts('Server running at http://127.0.0.1:8000/');
|
25
|
+
</pre>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Node.js">Wikipedia.org</em>.
|
29
|
+
</p>
|
30
|
+
</div>
|
31
|
+
</body>
|
32
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
<p class="excerpt">
|
8
|
+
Ruby is a dynamic, reflective, general purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto. It was influenced primarily by Perl, Smalltalk, Eiffel, and Lisp.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Ruby supports multiple programming paradigms, including functional, object oriented, imperative and reflective. It also has a dynamic type system and automatic memory management; it is therefore similar in varying respects to Python, Perl, Lisp, Dylan, Pike, and CLU.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
The standard 1.8.7 implementation is written in C, as a single-pass interpreted language. There is currently no specification of the Ruby language, so the original implementation is considered to be the de facto reference. As of 2010[update], there are a number of complete or upcoming alternative implementations of the Ruby language, including YARV, JRuby, Rubinius, IronRuby, MacRuby, and HotRuby, each of which takes a different approach, with IronRuby, JRuby and MacRuby providing just-in-time compilation and MacRuby also providing ahead-of-time compilation. The official 1.9 branch uses YARV, as will 2.0 (development), and will eventually supersede the slower Ruby MRI.
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<p>
|
20
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Wikipedia.org</em>.
|
21
|
+
</p>
|
22
|
+
</div>
|
23
|
+
</body>
|
24
|
+
</html>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Node.js Asynchronous JavaScript Framework
|
8
|
+
Ruby Programming Language
|
9
|
+
</div>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Node.js Asynchronous JavaScript Framework
|
8
|
+
</div>
|
9
|
+
</body>
|
10
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Node.js Asynchronous JavaScript Framework
|
8
|
+
</div>
|
9
|
+
</body>
|
10
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Ruby Programming Language
|
8
|
+
</div>
|
9
|
+
</body>
|
10
|
+
</html>
|
data/example/rules.rb
ADDED
data/example/tasks.rb
ADDED
File without changes
|
data/lib/ace.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# === The boot process === #
|
4
|
+
# 1) load the app
|
5
|
+
# 2) load the rules (controllers / globs mapping)
|
6
|
+
# 3) load & instantiate all the renderable items
|
7
|
+
# 4) render all the items (here the filters & layouting run)
|
8
|
+
# 5) match the routes, write the files
|
9
|
+
|
10
|
+
require "yaml"
|
11
|
+
require "fileutils"
|
12
|
+
|
13
|
+
module Ace
|
14
|
+
class RawItem
|
15
|
+
attr_accessor :path, :metadata, :content
|
16
|
+
def initialize(path)
|
17
|
+
@data = File.read(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse
|
21
|
+
pieces = @data.split(/^-{3,5}\s*$/)
|
22
|
+
if pieces.size < 3
|
23
|
+
raise RuntimeError.new(
|
24
|
+
"The file '#{content_filename}' appears to start with a metadata section (three or five dashes at the top) but it does not seem to be in the correct format."
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parse
|
29
|
+
self.metadata = YAML.load(pieces[1]).inject(Hash.new) { |metadata, pair| metadata.merge(pair[0].to_sym => pair[1]) } || Hash.new
|
30
|
+
self.content = pieces[2..-1].join.strip
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# This class represents the items which will be
|
35
|
+
# eventually rendered like concrete posts, tags etc.
|
36
|
+
class Item
|
37
|
+
def self.inherited(subclass)
|
38
|
+
self.subclasses << subclass
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.subclasses
|
42
|
+
@subclasses ||= Array.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.instances
|
46
|
+
@instances ||= Array.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.all_subclasses
|
50
|
+
self.subclasses + self.subclasses.map(&:subclasses).flatten
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.all_instances
|
54
|
+
self.all_subclasses.map(&:instances).flatten
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.before_filters
|
58
|
+
@before_filters ||= Array.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.before(filter, *args)
|
62
|
+
self.before_filters << filter.new(*args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.after_filters
|
66
|
+
@after_filters ||= Array.new
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.after(filter, *args)
|
70
|
+
self.after_filters << filter.new(*args)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.create(metadata, content)
|
74
|
+
self.new(metadata, content).tap(&:register)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Content can be anything, not just a string.
|
78
|
+
attr_accessor :metadata, :content
|
79
|
+
attr_accessor :original_path
|
80
|
+
def initialize(metadata, content)
|
81
|
+
@metadata = metadata
|
82
|
+
@content = content
|
83
|
+
end
|
84
|
+
|
85
|
+
def config
|
86
|
+
@config ||= begin
|
87
|
+
YAML::load_file("config.yml").inject(Hash.new) do |hash, pair|
|
88
|
+
hash.merge!(pair[0].to_sym => pair[1])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def register
|
94
|
+
instances = self.class.instances
|
95
|
+
unless instances.include?(self)
|
96
|
+
self.class.instances << self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def unregister
|
101
|
+
self.class.instances.delete(self)
|
102
|
+
end
|
103
|
+
|
104
|
+
def render
|
105
|
+
output = self.class.before_filters.inject(self.content) do |buffer, filter|
|
106
|
+
filter.call(self, buffer)
|
107
|
+
end
|
108
|
+
|
109
|
+
self.class.after_filters.inject(output) do |buffer, filter|
|
110
|
+
filter.call(self, buffer)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
attr_writer :output_path
|
115
|
+
def output_path
|
116
|
+
@output_path ||= begin
|
117
|
+
unless self.original_path.nil?
|
118
|
+
self.original_path.sub("content", "output")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def save!
|
124
|
+
content = self.render # so filters can influence output_path
|
125
|
+
|
126
|
+
FileUtils.mkdir_p File.dirname(self.output_path)
|
127
|
+
File.open(self.output_path, "w") do |file|
|
128
|
+
file.puts(content)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class Asset < Item
|
134
|
+
end
|
135
|
+
|
136
|
+
module Helpers
|
137
|
+
def link_to(anchor, path_or_item, options = nil)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/lib/ace/dsl.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Ace
|
4
|
+
class DSL
|
5
|
+
attr_accessor :rules, :generators
|
6
|
+
def initialize
|
7
|
+
@rules, @generators = Hash.new, Array.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule(klass, *globs)
|
11
|
+
paths = globs.map { |glob| Dir.glob("content/#{glob}") }
|
12
|
+
files = paths.flatten.select { |path| File.file?(path) }
|
13
|
+
self.rules[klass] ||= Array.new
|
14
|
+
self.rules[klass].push(*files)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generator(klass)
|
18
|
+
self.generators << klass
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ace/filters.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "haml"
|
4
|
+
require "ace/filters"
|
5
|
+
|
6
|
+
# This is just a plain Haml, no template inheritance.
|
7
|
+
module Ace
|
8
|
+
class HamlFilter < Filter
|
9
|
+
# http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml/Engine.html
|
10
|
+
def call(item, content)
|
11
|
+
if item.output_path && item.output_path.end_with?(".haml")
|
12
|
+
item.output_path.sub!(/\.haml$/, "")
|
13
|
+
end
|
14
|
+
|
15
|
+
engine = Haml::Engine.new(content)
|
16
|
+
engine.render(item.extend(Ace::Helpers))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "ace/filters"
|
4
|
+
require "template-inheritance"
|
5
|
+
|
6
|
+
layouts = File.join(Dir.pwd, "layouts")
|
7
|
+
unless TemplateInheritance::Template.paths.include?(layouts)
|
8
|
+
TemplateInheritance::Template.paths.unshift(layouts)
|
9
|
+
end
|
10
|
+
|
11
|
+
module Ace
|
12
|
+
class LayoutFilter < Filter
|
13
|
+
def initialize(options)
|
14
|
+
@path = options[:layout]
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(item, content)
|
18
|
+
template = TemplateInheritance::Template.new(@path)
|
19
|
+
return template.render(item: item)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "ace/filters"
|
4
|
+
require "template-inheritance"
|
5
|
+
|
6
|
+
layouts = File.join(Dir.pwd, "layouts")
|
7
|
+
unless TemplateInheritance::Template.paths.include?(layouts)
|
8
|
+
TemplateInheritance::Template.paths.unshift(layouts)
|
9
|
+
end
|
10
|
+
|
11
|
+
TemplateInheritance::Template.paths << File.join(Dir.pwd, "content")
|
12
|
+
|
13
|
+
module Ace
|
14
|
+
class TemplateFilter < Filter
|
15
|
+
def call(item, content)
|
16
|
+
if item.output_path
|
17
|
+
item.output_path = item.output_path.split(".")[0..-2].join(".")
|
18
|
+
end
|
19
|
+
|
20
|
+
relative_path = item.original_path.sub("content/", "")
|
21
|
+
template = TemplateInheritance::Template.new(relative_path)
|
22
|
+
return template.render(item: item)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ace/version.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This hook will be executed after templater finish in context of current generator object.
|
4
|
+
# Current directory is what you just generated, unless this is flat generator.
|
5
|
+
|
6
|
+
unless RUBY_PLATFORM.match(/mswin|mingw/)
|
7
|
+
sh "chmod +x boot.rb"
|
8
|
+
sh "chmod +x tasks.rb"
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This hook will be executed in context of current generator object before templater start to generate new files.
|
4
|
+
# You can update context hash and register hooks. Don't forget to use merge! instead of merge, because you are
|
5
|
+
# manipulating with one object, rather than returning new one.
|
6
|
+
|
7
|
+
hook do |generator, context|
|
8
|
+
# TODO
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ace
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- "Jakub \xC5\xA0\xC5\xA5astn\xC3\xBD aka Botanicus"
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain:
|
15
|
+
date: 2011-02-17 00:00:00 +00:00
|
16
|
+
default_executable: ace
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
19
|
+
name: template-inheritance
|
20
|
+
prerelease: false
|
21
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
version: "0"
|
29
|
+
type: :runtime
|
30
|
+
version_requirements: *id001
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: simple-templater
|
33
|
+
prerelease: false
|
34
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
- 0
|
42
|
+
- 1
|
43
|
+
- 2
|
44
|
+
version: 0.0.1.2
|
45
|
+
type: :development
|
46
|
+
version_requirements: *id002
|
47
|
+
description: ""
|
48
|
+
email: stastny@101ideas.cz
|
49
|
+
executables:
|
50
|
+
- ace
|
51
|
+
- ace-gen
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files: []
|
55
|
+
|
56
|
+
files:
|
57
|
+
- .gitignore
|
58
|
+
- CHANGELOG
|
59
|
+
- LICENSE
|
60
|
+
- README.textile
|
61
|
+
- TODO
|
62
|
+
- ace.gemspec
|
63
|
+
- ace.pre.gemspec
|
64
|
+
- bin/ace
|
65
|
+
- bin/ace-gen
|
66
|
+
- example/app/posts.rb
|
67
|
+
- example/app/tags.rb
|
68
|
+
- example/boot.rb
|
69
|
+
- example/config.yml
|
70
|
+
- example/content/assets/css/style.css
|
71
|
+
- example/content/assets/js/application.js
|
72
|
+
- example/content/index.html.haml
|
73
|
+
- example/content/posts.json.rb
|
74
|
+
- example/content/posts/node-js.html
|
75
|
+
- example/content/posts/ruby.html
|
76
|
+
- example/layouts/base.html.haml
|
77
|
+
- example/layouts/post.html.haml
|
78
|
+
- example/layouts/tag.html.haml
|
79
|
+
- example/lib/initializer.rb
|
80
|
+
- example/output/assets/css/style.css
|
81
|
+
- example/output/assets/js/application.js
|
82
|
+
- example/output/posts/node-js.html
|
83
|
+
- example/output/posts/ruby.html
|
84
|
+
- example/output/posts/test.html
|
85
|
+
- example/output/tags/development.html
|
86
|
+
- example/output/tags/javascript.html
|
87
|
+
- example/output/tags/node.js.html
|
88
|
+
- example/output/tags/ruby.html
|
89
|
+
- example/rules.rb
|
90
|
+
- example/tasks.rb
|
91
|
+
- lib/ace.rb
|
92
|
+
- lib/ace/dsl.rb
|
93
|
+
- lib/ace/filters.rb
|
94
|
+
- lib/ace/filters/haml.rb
|
95
|
+
- lib/ace/filters/layout.rb
|
96
|
+
- lib/ace/filters/template.rb
|
97
|
+
- lib/ace/version.rb
|
98
|
+
- project_generator/metadata.yml
|
99
|
+
- project_generator/postprocess.rb
|
100
|
+
- project_generator/setup.rb
|
101
|
+
- simple-templater.scope
|
102
|
+
has_rdoc: true
|
103
|
+
homepage: http://github.com/botanicus/ace
|
104
|
+
licenses: []
|
105
|
+
|
106
|
+
post_install_message: "[\e[32mVersion 0.0.1\e[0m] Items\n\
|
107
|
+
[\e[32mVersion 0.0.1\e[0m] Generators\n"
|
108
|
+
rdoc_options: []
|
109
|
+
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
segments:
|
118
|
+
- 1
|
119
|
+
- 9
|
120
|
+
version: "1.9"
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
requirements: []
|
130
|
+
|
131
|
+
rubyforge_project: ace
|
132
|
+
rubygems_version: 1.3.7
|
133
|
+
signing_key:
|
134
|
+
specification_version: 3
|
135
|
+
summary: Ace is highly flexible static pages generator with template inheritance.
|
136
|
+
test_files: []
|
137
|
+
|