malt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +13 -0
- data/License.txt +204 -0
- data/README.rdoc +68 -0
- data/bin/malt +4 -0
- data/features/consistent_rendering.feature +36 -0
- data/features/samples/sample.erb +1 -0
- data/features/samples/sample.erubis +1 -0
- data/features/samples/sample.liquid +1 -0
- data/features/samples/sample.mustache +1 -0
- data/features/samples/sample.radius +1 -0
- data/features/step_definitions/engine_steps.rb +49 -0
- data/features/support/loadpath.rb +1 -0
- data/features/support/sample_class.rb +8 -0
- data/lib/malt.rb +79 -0
- data/lib/malt/core_ext.rb +31 -0
- data/lib/malt/engines.rb +10 -0
- data/lib/malt/engines/abstract.rb +151 -0
- data/lib/malt/engines/bluecloth.rb +39 -0
- data/lib/malt/engines/erb.rb +84 -0
- data/lib/malt/engines/erubis.rb +65 -0
- data/lib/malt/engines/haml.rb +68 -0
- data/lib/malt/engines/kramdown.rb +48 -0
- data/lib/malt/engines/less.rb +49 -0
- data/lib/malt/engines/liquid.rb +40 -0
- data/lib/malt/engines/radius.rb +90 -0
- data/lib/malt/engines/rdiscount.rb +49 -0
- data/lib/malt/engines/rdoc.rb +46 -0
- data/lib/malt/engines/redcloth.rb +42 -0
- data/lib/malt/engines/rtals.rb +46 -0
- data/lib/malt/engines/ruby.rb +36 -0
- data/lib/malt/engines/sass.rb +50 -0
- data/lib/malt/engines/tenjin.rb +61 -0
- data/lib/malt/formats.rb +10 -0
- data/lib/malt/formats/abstract.rb +195 -0
- data/lib/malt/formats/css.rb +34 -0
- data/lib/malt/formats/erb.rb +102 -0
- data/lib/malt/formats/haml.rb +53 -0
- data/lib/malt/formats/html.rb +29 -0
- data/lib/malt/formats/latex.rb +47 -0
- data/lib/malt/formats/less.rb +51 -0
- data/lib/malt/formats/liquid.rb +53 -0
- data/lib/malt/formats/markdown.rb +83 -0
- data/lib/malt/formats/pdf.rb +29 -0
- data/lib/malt/formats/radius.rb +47 -0
- data/lib/malt/formats/rdoc.rb +43 -0
- data/lib/malt/formats/rtals.rb +46 -0
- data/lib/malt/formats/ruby.rb +71 -0
- data/lib/malt/formats/sass.rb +56 -0
- data/lib/malt/formats/tenjin.rb +50 -0
- data/lib/malt/formats/text.rb +54 -0
- data/lib/malt/formats/textile.rb +59 -0
- data/lib/malt/formats/yaml.rb +50 -0
- data/lib/malt/kernel.rb +31 -0
- data/lib/malt/meta/data.rb +26 -0
- data/lib/malt/meta/gemfile +17 -0
- data/lib/malt/meta/profile +21 -0
- data/meta/data.rb +26 -0
- data/meta/gemfile +17 -0
- data/meta/profile +21 -0
- data/qed/01_overview.rdoc +44 -0
- data/qed/applique/malt.rb +12 -0
- 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
|
data/lib/malt/engines.rb
ADDED
@@ -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
|
+
|