ace 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG +3 -0
  3. data/LICENSE +20 -0
  4. data/README.textile +18 -0
  5. data/TODO +1 -0
  6. data/ace.gemspec +53 -0
  7. data/ace.pre.gemspec +6 -0
  8. data/bin/ace +76 -0
  9. data/bin/ace-gen +32 -0
  10. data/example/app/posts.rb +20 -0
  11. data/example/app/tags.rb +28 -0
  12. data/example/boot.rb +6 -0
  13. data/example/config.yml +2 -0
  14. data/example/content/assets/css/style.css +1 -0
  15. data/example/content/assets/js/application.js +3 -0
  16. data/example/content/index.html.haml +5 -0
  17. data/example/content/posts.json.rb +0 -0
  18. data/example/content/posts/node-js.html +29 -0
  19. data/example/content/posts/ruby.html +21 -0
  20. data/example/layouts/base.html.haml +5 -0
  21. data/example/layouts/post.html.haml +5 -0
  22. data/example/layouts/tag.html.haml +6 -0
  23. data/example/lib/initializer.rb +0 -0
  24. data/example/output/assets/css/style.css +1 -0
  25. data/example/output/assets/js/application.js +3 -0
  26. data/example/output/posts/node-js.html +32 -0
  27. data/example/output/posts/ruby.html +24 -0
  28. data/example/output/posts/test.html +10 -0
  29. data/example/output/tags/development.html +11 -0
  30. data/example/output/tags/javascript.html +10 -0
  31. data/example/output/tags/node.js.html +10 -0
  32. data/example/output/tags/ruby.html +10 -0
  33. data/example/rules.rb +8 -0
  34. data/example/tasks.rb +0 -0
  35. data/lib/ace.rb +140 -0
  36. data/lib/ace/dsl.rb +21 -0
  37. data/lib/ace/filters.rb +9 -0
  38. data/lib/ace/filters/haml.rb +19 -0
  39. data/lib/ace/filters/layout.rb +22 -0
  40. data/lib/ace/filters/template.rb +25 -0
  41. data/lib/ace/version.rb +5 -0
  42. data/project_generator/metadata.yml +3 -0
  43. data/project_generator/postprocess.rb +9 -0
  44. data/project_generator/setup.rb +9 -0
  45. data/simple-templater.scope +6 -0
  46. metadata +137 -0
@@ -0,0 +1,3 @@
1
+ /*.gem
2
+ .DS_Store
3
+ .rvmrc
@@ -0,0 +1,3 @@
1
+ = Version 0.0.1
2
+ * Items
3
+ * Generators
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.
@@ -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/TODO ADDED
@@ -0,0 +1 @@
1
+ - ace-gen myproject
@@ -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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env gem build
2
+ # encoding: utf-8
3
+
4
+ eval(File.read("ace.gemspec")).tap do |specification|
5
+ specification.version = "#{specification.version}.pre"
6
+ end
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
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ace
2
+ # encoding: utf-8
3
+
4
+ Dir["app/**/*.rb"].each do |file|
5
+ load file
6
+ end
@@ -0,0 +1,2 @@
1
+ title: ""
2
+ base_url: ""
@@ -0,0 +1 @@
1
+ h1 { color: red; }
@@ -0,0 +1,3 @@
1
+ window.onload = function () {
2
+ console.log("I don't do nothing really, I'm just pretending to be a useful asset.");
3
+ };
@@ -0,0 +1,5 @@
1
+ - extends "base.html"
2
+
3
+ - Post.each do |post|
4
+ %h2= post.title
5
+ = post.excerpt
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>
@@ -0,0 +1,5 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %body
5
+ #main= block(:body)
@@ -0,0 +1,5 @@
1
+ - extends "base.html"
2
+
3
+ - block(:body) do
4
+ %h1 My Coooooool Bloogiiiiseeeeek!
5
+ = item.content
@@ -0,0 +1,6 @@
1
+ - extends "base.html"
2
+
3
+ - block(:body) do
4
+ %h1 My Coooooool Bloogiiiiseeeeek!
5
+ - item.content.each do |post|
6
+ = post.metadata[:title]
File without changes
@@ -0,0 +1 @@
1
+ h1 { color: red; }
@@ -0,0 +1,3 @@
1
+ window.onload = function () {
2
+ console.log("I don't do nothing really, I'm just pretending to be a useful asset.");
3
+ };
@@ -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,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
+ content
8
+ </div>
9
+ </body>
10
+ </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>
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ # filters
4
+ rule Post, "posts/*.html"
5
+ rule Ace::Asset, "assets/**/*"
6
+
7
+ # generators
8
+ generator TagPagesGenerator#, "/tags/:slug"
File without changes
@@ -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
@@ -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
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ module Ace
4
+ class Filter
5
+ def initialize(options = Hash.new)
6
+ @options = options
7
+ end
8
+ end
9
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Ace
4
+ VERSION = "0.1"
5
+ end
@@ -0,0 +1,3 @@
1
+ ---
2
+ :full: yes
3
+ :flat: no
@@ -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
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ SimpleTemplater.scope(:ace) do
4
+ path = File.expand_path("../project_generator", __FILE__)
5
+ SimpleTemplater.register(:ace, :project, File.expand_path(path))
6
+ 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
+