malt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/History.rdoc +13 -0
  2. data/License.txt +204 -0
  3. data/README.rdoc +68 -0
  4. data/bin/malt +4 -0
  5. data/features/consistent_rendering.feature +36 -0
  6. data/features/samples/sample.erb +1 -0
  7. data/features/samples/sample.erubis +1 -0
  8. data/features/samples/sample.liquid +1 -0
  9. data/features/samples/sample.mustache +1 -0
  10. data/features/samples/sample.radius +1 -0
  11. data/features/step_definitions/engine_steps.rb +49 -0
  12. data/features/support/loadpath.rb +1 -0
  13. data/features/support/sample_class.rb +8 -0
  14. data/lib/malt.rb +79 -0
  15. data/lib/malt/core_ext.rb +31 -0
  16. data/lib/malt/engines.rb +10 -0
  17. data/lib/malt/engines/abstract.rb +151 -0
  18. data/lib/malt/engines/bluecloth.rb +39 -0
  19. data/lib/malt/engines/erb.rb +84 -0
  20. data/lib/malt/engines/erubis.rb +65 -0
  21. data/lib/malt/engines/haml.rb +68 -0
  22. data/lib/malt/engines/kramdown.rb +48 -0
  23. data/lib/malt/engines/less.rb +49 -0
  24. data/lib/malt/engines/liquid.rb +40 -0
  25. data/lib/malt/engines/radius.rb +90 -0
  26. data/lib/malt/engines/rdiscount.rb +49 -0
  27. data/lib/malt/engines/rdoc.rb +46 -0
  28. data/lib/malt/engines/redcloth.rb +42 -0
  29. data/lib/malt/engines/rtals.rb +46 -0
  30. data/lib/malt/engines/ruby.rb +36 -0
  31. data/lib/malt/engines/sass.rb +50 -0
  32. data/lib/malt/engines/tenjin.rb +61 -0
  33. data/lib/malt/formats.rb +10 -0
  34. data/lib/malt/formats/abstract.rb +195 -0
  35. data/lib/malt/formats/css.rb +34 -0
  36. data/lib/malt/formats/erb.rb +102 -0
  37. data/lib/malt/formats/haml.rb +53 -0
  38. data/lib/malt/formats/html.rb +29 -0
  39. data/lib/malt/formats/latex.rb +47 -0
  40. data/lib/malt/formats/less.rb +51 -0
  41. data/lib/malt/formats/liquid.rb +53 -0
  42. data/lib/malt/formats/markdown.rb +83 -0
  43. data/lib/malt/formats/pdf.rb +29 -0
  44. data/lib/malt/formats/radius.rb +47 -0
  45. data/lib/malt/formats/rdoc.rb +43 -0
  46. data/lib/malt/formats/rtals.rb +46 -0
  47. data/lib/malt/formats/ruby.rb +71 -0
  48. data/lib/malt/formats/sass.rb +56 -0
  49. data/lib/malt/formats/tenjin.rb +50 -0
  50. data/lib/malt/formats/text.rb +54 -0
  51. data/lib/malt/formats/textile.rb +59 -0
  52. data/lib/malt/formats/yaml.rb +50 -0
  53. data/lib/malt/kernel.rb +31 -0
  54. data/lib/malt/meta/data.rb +26 -0
  55. data/lib/malt/meta/gemfile +17 -0
  56. data/lib/malt/meta/profile +21 -0
  57. data/meta/data.rb +26 -0
  58. data/meta/gemfile +17 -0
  59. data/meta/profile +21 -0
  60. data/qed/01_overview.rdoc +44 -0
  61. data/qed/applique/malt.rb +12 -0
  62. metadata +283 -0
@@ -0,0 +1,31 @@
1
+ require 'ostruct'
2
+ require 'facets/module/basename'
3
+
4
+ class Hash
5
+
6
+ #
7
+ def to_hash
8
+ dup
9
+ end unless method_defined?(:to_hash)
10
+
11
+ #
12
+ def rekey(&block)
13
+ h = {}
14
+ if block
15
+ each{|k,v| h[block[k]] = v }
16
+ else
17
+ each{|k,v| h[k.to_sym] = v }
18
+ end
19
+ h
20
+ end unless method_defined?(:rekey)
21
+
22
+ end
23
+
24
+ class OpenStruct
25
+
26
+ #
27
+ def to_hash
28
+ @table.dup
29
+ end unless method_defined?(:to_hash)
30
+
31
+ end
@@ -0,0 +1,10 @@
1
+ module Malt
2
+ #
3
+ module Engines
4
+ end
5
+ end
6
+
7
+ Dir[File.dirname(__FILE__) + '/engines/*.rb'].each do |file|
8
+ require file
9
+ end
10
+
@@ -0,0 +1,151 @@
1
+ require 'malt/kernel'
2
+
3
+ module Malt
4
+ module Engines
5
+
6
+ class << self
7
+ include Malt::Kernel
8
+ end
9
+
10
+ #
11
+ def self.register(malt_class, *exts)
12
+ exts.each do |ext|
13
+ type = ext_to_type(ext)
14
+ registry[type] ||= []
15
+ registry[type] << malt_class
16
+ registry[type].uniq!
17
+ end
18
+ end
19
+
20
+ #
21
+ def self.registry
22
+ @registry ||= {}
23
+ end
24
+
25
+
26
+ # Abstract Template class serves as the base
27
+ # class for all other Template classes.
28
+ #
29
+ class Abstract
30
+ include Malt::Kernel
31
+
32
+ # Register the class to an extension type.
33
+ def self.register(*exts)
34
+ Engines.register(self, *exts)
35
+ end
36
+
37
+ # Register and set as the default for given extensions.
38
+ def self.default(*exts)
39
+ register(*exts)
40
+ exts.each do |ext|
41
+ Malt.config.engine[ext.to_sym] = self
42
+ end
43
+ end
44
+
45
+ # Override this method to load rendering engine library.
46
+ def initialize(settings={})
47
+ @settings = settings.rekey
48
+
49
+ @cache = {}
50
+ @source = {}
51
+
52
+ initialize_engine
53
+ end
54
+
55
+ # Access to the options given to the initializer.
56
+ # Returns an OpenStruct object.
57
+ attr :settings
58
+
59
+ #
60
+ def render(text, options={}) #format, text, file, db, &yld)
61
+ if format = options[:format]
62
+ raise "unsupported rendering -- #{format}"
63
+ else
64
+ raise "unsupported rendering"
65
+ end
66
+ end
67
+
68
+ #
69
+ def compile(db, &yld)
70
+ raise "not implemented"
71
+ end
72
+
73
+ #
74
+ def cache?
75
+ !settings[:nocache]
76
+ end
77
+
78
+ private
79
+
80
+ # Override this to load template engine library and
81
+ # prepare is for geeral usage.
82
+ def initialize_engine
83
+ end
84
+
85
+ # Require template library.
86
+ def require_library(path)
87
+ require(path)
88
+ end
89
+
90
+ # Convert a data source into a Binding.
91
+ # TODO: handle yld.
92
+ def make_binding(db, &yld)
93
+ return db if Binding === db
94
+
95
+ if db.respond_to?(:to_binding)
96
+ return db.to_binding
97
+ end
98
+
99
+ db = make_object(db)
100
+
101
+ return db.instance_eval{ binding }
102
+ end
103
+
104
+ # Convert a data source into an Object (aka a "scope").
105
+ def make_object(db)
106
+ if db.respond_to?(:to_hash)
107
+ hash = db.to_hash
108
+ attrs = hash.keys.map{ |k| k.to_sym }
109
+ return Struct.new(*attrs).new(*hash.values)
110
+ end
111
+
112
+ if Binding === db
113
+ eval('self', binding)
114
+ end
115
+
116
+ return db
117
+ end
118
+
119
+ # Convert a data source into a Hash.
120
+ def make_hash(db, &yld)
121
+ if Binding === db
122
+ db = make_object(db)
123
+ end
124
+
125
+ if db.respond_to?(:to_hash)
126
+ db = db.to_hash
127
+ db[:yield] = yld.call if yld
128
+ return db
129
+ end
130
+
131
+ if db.respond_to?(:to_h)
132
+ db = db.to_h
133
+ db[:yield] = yld.call if yld
134
+ return db
135
+ end
136
+
137
+ # last resort
138
+ db = db.instance_variables.inject({}) do |h, i|
139
+ k = i.sub('@','').to_sym
140
+ v = instance_variable_get(i)
141
+ h[k] = v
142
+ h
143
+ end
144
+ db[:yield] = yld.call if yld
145
+ return db
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,39 @@
1
+ require 'malt/engines/abstract'
2
+
3
+ module Malt::Engines
4
+
5
+ #
6
+ class BlueCloth < Abstract
7
+
8
+ register :markdown, :md
9
+
10
+ # Convert Markdown text to HTML text.
11
+ def render(params)
12
+ text = params[:text]
13
+ format = params[:format]
14
+ case format
15
+ when :html, nil
16
+ intermediate(params).to_html
17
+ else
18
+ super(params)
19
+ end
20
+ end
21
+
22
+ # Convert Markdown text to intermediate object.
23
+ def intermediate(params)
24
+ text = params[:text]
25
+ ::BlueCloth.new(text)
26
+ end
27
+
28
+ private
29
+
30
+ # Load bluecloth library if not already loaded.
31
+ def initialize_engine
32
+ return if defined? ::BlueCloth
33
+ require_library 'bluecloth'
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,84 @@
1
+ require 'malt/engines/abstract'
2
+
3
+ module Malt::Engines
4
+
5
+ # ERB template implementation.
6
+ #
7
+ # http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html
8
+ #
9
+ # ERB templates accept two options. +safe+ sets the safe mode for
10
+ # rendering the template and +trim+ is a weird string that controls
11
+ # a few rendering options --it can be '%' and/or '>' or '<>'.
12
+ class Erb < Abstract
13
+
14
+ default :erb, :rhtml
15
+
16
+ # Render ERB template.
17
+ #
18
+ # The +params+ can be:
19
+ #
20
+ # * :text - text of erb document
21
+ # * :file - file name where text was read (or nil)
22
+ # * :data - data source for template interpolation
23
+ # * :safe -
24
+ # * :trim -
25
+ #
26
+ # Returns a String.
27
+ def render(params={}, &yld)
28
+ text = params[:text]
29
+ file = params[:file]
30
+ data = params[:data]
31
+ data = make_binding(data, &yld)
32
+ if settings[:precompile] == false
33
+ intermediate(params).result(data)
34
+ else
35
+ ruby = compile(params)
36
+ eval(ruby, data, file)
37
+ end
38
+ end
39
+
40
+ # Compile ERB template into Ruby source code.
41
+ def compile(params={})
42
+ file = params[:file]
43
+ if cache?
44
+ @source[file] ||= intermediate(params).src
45
+ else
46
+ intermediate(params).src
47
+ end
48
+ end
49
+
50
+ # Returns instance of underlying ::ERB class.
51
+ def intermediate(params={})
52
+ text = params[:text]
53
+ file = params[:file]
54
+
55
+ opts = engine_options(params)
56
+ safe = opts[:safe]
57
+ trim = opts[:trim]
58
+
59
+ if cache?
60
+ @cache[file] ||= ::ERB.new(text, safe, trim)
61
+ else
62
+ ::ERB.new(text, safe, trim)
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ # Load ERB library if not already loaded.
69
+ def initialize_engine
70
+ return if defined? ::ERB
71
+ require_library('erb')
72
+ end
73
+
74
+ def engine_options(params)
75
+ opts = {}
76
+ opts[:safe] = params[:safe] || settings[:safe]
77
+ opts[:trim] = params[:trim] || settings[:trim]
78
+ opts
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,65 @@
1
+ require 'malt/engines/abstract'
2
+
3
+ module Malt::Engines
4
+
5
+ # Erubis template implementation.
6
+ #
7
+ # http://www.kuwata-lab.com/erubis/
8
+ #
9
+ # Erubis is essentially compatibel with ERB, but it is faster.
10
+ #
11
+ class Erubis < Abstract
12
+
13
+ register :erb, :rhtml
14
+
15
+ # Render template.
16
+ def render(params, &yld)
17
+ text = params[:text]
18
+ data = params[:data]
19
+ data = make_binding(data, &yld)
20
+ intermediate(params).result(data)
21
+ end
22
+
23
+ # Compile template into Ruby source code.
24
+ def compile(params)
25
+ text = params[:text]
26
+ file = params[:file]
27
+ intermediate(text, file).src
28
+ end
29
+
30
+ #
31
+ def intermediate(params)
32
+ text = params[:text]
33
+ file = params[:file]
34
+
35
+ opts = {}
36
+
37
+ if params[:escape_html] || settings[:escape_html]
38
+ ::Erubis::EscapedEruby.new(text, settings)
39
+ else
40
+ ::Erubis::Eruby.new(text, settings)
41
+ end
42
+ end
43
+
44
+ #
45
+ def safe
46
+ options[:safe]
47
+ end
48
+
49
+ #
50
+ def trim
51
+ options[:trim]
52
+ end
53
+
54
+ ;;;; private ;;;;
55
+
56
+ # Load ERB library if not already loaded.
57
+ def initialize_engine
58
+ return if defined? ::Erubius
59
+ require_library('erubis')
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
@@ -0,0 +1,68 @@
1
+ require 'malt/engines/abstract'
2
+
3
+ module Malt::Engines
4
+
5
+ # Haml
6
+ #
7
+ class Haml < Abstract
8
+
9
+ default :haml
10
+
11
+ #
12
+ def render(params, &yld)
13
+ format = params[:format]
14
+ case format
15
+ when :html, nil
16
+ render_html(params, &yld)
17
+ else
18
+ super(params, &yld)
19
+ end
20
+ end
21
+
22
+ #
23
+ def render_html(params, &yld)
24
+ text = params[:text]
25
+ file = params[:file]
26
+ data = params[:data]
27
+
28
+ engine = intermediate(params)
29
+ case data
30
+ when Binding
31
+ html = engine.render(make_object(data), &yld)
32
+ when Hash
33
+ html = engine.render(Object.new, data, &yld)
34
+ else
35
+ if data.respond_to?(:to_hash)
36
+ data = data.to_hash
37
+ html = engine.render(Object.new, data, &yld)
38
+ else
39
+ html = engine.render(data || Object.new, &yld)
40
+ end
41
+ end
42
+ html
43
+ end
44
+
45
+ #
46
+ #def compile(text, file)
47
+ # intermediate # ??
48
+ #end
49
+
50
+ #
51
+ def intermediate(params)
52
+ text = params[:text]
53
+ file = params[:file]
54
+ ::Haml::Engine.new(text, :filename=>file)
55
+ end
56
+
57
+ private
58
+
59
+ # Load Haml library if not already loaded.
60
+ def initialize_engine
61
+ return if defined? ::Haml::Engine
62
+ require_library 'haml'
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+