malt 0.1.0
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/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
|
+
|