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.
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
+