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,50 @@
|
|
1
|
+
require 'malt/engines/abstract'
|
2
|
+
|
3
|
+
module Malt::Engines
|
4
|
+
|
5
|
+
# Sass Malt Engine
|
6
|
+
#
|
7
|
+
class Sass < Abstract
|
8
|
+
|
9
|
+
default :sass, :scss
|
10
|
+
|
11
|
+
#
|
12
|
+
def render(params, &yld)
|
13
|
+
text = params[:text]
|
14
|
+
file = params[:file]
|
15
|
+
format = params[:format]
|
16
|
+
|
17
|
+
case format
|
18
|
+
when :css, nil
|
19
|
+
engine = intermediate(params)
|
20
|
+
engine.render
|
21
|
+
else
|
22
|
+
super(params, &yld)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
def intermediate(params)
|
28
|
+
text = params[:text]
|
29
|
+
file = params[:file]
|
30
|
+
type = params[:type]
|
31
|
+
::Sass::Engine.new(text, :filename=>file, :syntax=>type)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Load Sass library if not already loaded.
|
37
|
+
def initialize_engine
|
38
|
+
return if defined? ::Sass::Engine
|
39
|
+
require_library 'sass'
|
40
|
+
end
|
41
|
+
|
42
|
+
def engine_options
|
43
|
+
opts = {}
|
44
|
+
opts
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'malt/engines/abstract'
|
2
|
+
|
3
|
+
module Malt::Engines
|
4
|
+
|
5
|
+
# Tenjin
|
6
|
+
#
|
7
|
+
# http://www.kuwata-lab.com/tenjin/
|
8
|
+
#
|
9
|
+
# options
|
10
|
+
# :escapefunc=>'CGI.escapeHTML'
|
11
|
+
#
|
12
|
+
class Tenjin < Abstract
|
13
|
+
|
14
|
+
default :tenjin, :rbhtml
|
15
|
+
|
16
|
+
#
|
17
|
+
def render(params, &yld)
|
18
|
+
text = params[:text]
|
19
|
+
file = params[:file]
|
20
|
+
data = params[:data]
|
21
|
+
type = params[:type]
|
22
|
+
format = params[:format] || :html
|
23
|
+
|
24
|
+
return super(params, &yld) if type == :rbhtml && format != :html
|
25
|
+
|
26
|
+
data = make_hash(data, &yld)
|
27
|
+
template = intermediate(params)
|
28
|
+
template.convert(text, file)
|
29
|
+
|
30
|
+
template.render(data)
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
def compile(params)
|
35
|
+
text = params[:text]
|
36
|
+
file = params[:file]
|
37
|
+
intermediate(params).convert(text, file)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def intermediate(params)
|
43
|
+
::Tenjin::Template.new(nil, engine_options(params))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Load Liquid library if not already loaded.
|
47
|
+
def initialize_engine
|
48
|
+
return if defined? ::Tenjin::Engine
|
49
|
+
require_library 'tenjin'
|
50
|
+
end
|
51
|
+
|
52
|
+
def engine_options(params)
|
53
|
+
opts = {}
|
54
|
+
opts[:escapefunc] = params[:escapefunc] || settings[:escapefunc]
|
55
|
+
opts
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
data/lib/malt/formats.rb
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'malt/kernel'
|
2
|
+
|
3
|
+
module Malt
|
4
|
+
module Formats
|
5
|
+
|
6
|
+
# Abstract format class serves as the base
|
7
|
+
# class for all other format classes.
|
8
|
+
#
|
9
|
+
class Abstract
|
10
|
+
include Malt::Kernel
|
11
|
+
|
12
|
+
# Register the class to an extension type.
|
13
|
+
def self.register(*exts)
|
14
|
+
@extensions = exts
|
15
|
+
Malt.register(self, *exts)
|
16
|
+
|
17
|
+
#exts.each do |ext|
|
18
|
+
# Abstract.module_eval %{
|
19
|
+
# def to_#{ext}(*db,&yld)
|
20
|
+
# convert(:#{ext},*db,&yld)
|
21
|
+
# end
|
22
|
+
# }
|
23
|
+
#end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
def self.extensions
|
28
|
+
@extensions
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
def self.engine(set=nil)
|
33
|
+
@engine = set if set
|
34
|
+
@engine
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
#
|
40
|
+
def initialize(options={})
|
41
|
+
@options = options.rekey
|
42
|
+
@type = @options[:type]
|
43
|
+
initialize_engine
|
44
|
+
end
|
45
|
+
|
46
|
+
# Override this method to load rendering engine library.
|
47
|
+
def initialize_engine
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
public
|
52
|
+
|
53
|
+
# Access to the options given to the initializer.
|
54
|
+
attr :options
|
55
|
+
|
56
|
+
# Document source text.
|
57
|
+
def text
|
58
|
+
@text ||= options[:text] || File.read(file)
|
59
|
+
end
|
60
|
+
|
61
|
+
# File name of document.
|
62
|
+
def file
|
63
|
+
@file ||= options[:file].to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
# File extension (with prefixed dot).
|
67
|
+
def type
|
68
|
+
@type ||= File.extname(file)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Specified engine to use for rendering.
|
72
|
+
#
|
73
|
+
# Keep in mind that the ability to specify the engine
|
74
|
+
# varies based on engine, format and output format.
|
75
|
+
def engine
|
76
|
+
options[:engine] || self.class.engine
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
def to(type, data=nil, &yld)
|
81
|
+
__send__("to_#{type}", data, &yld)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Render to default or given format.
|
85
|
+
#
|
86
|
+
# If the first argument is a Symbol it is considered the format, otherwise
|
87
|
+
# it is taken to be the database for rendering template variables.
|
88
|
+
def render(*type_and_data, &yld)
|
89
|
+
type, data = parse_type_and_data(type_and_data)
|
90
|
+
__send__(type || default, data, &yld)
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
#def render_to(format, db=nil, &yld)
|
95
|
+
# render_engine.render(format, text, file, db, &yld)
|
96
|
+
#end
|
97
|
+
|
98
|
+
#
|
99
|
+
# def method_missing(s, *a, &b)
|
100
|
+
# case s.to_s
|
101
|
+
# when /^to_/
|
102
|
+
# convert($', *a, &b)
|
103
|
+
# else
|
104
|
+
# convert(s, *a, &b).to_s
|
105
|
+
# #render_to(s, *a, &b)
|
106
|
+
# end
|
107
|
+
# #rescue
|
108
|
+
# # super(s, *a, &b)
|
109
|
+
# #end
|
110
|
+
# end
|
111
|
+
|
112
|
+
# TODO: render a file until add extension are exhusted
|
113
|
+
# def convert(to, *db, &yld)
|
114
|
+
# db = db.first
|
115
|
+
# output = render_to(to, db, &yld)
|
116
|
+
# if subclass = Malt.registry[subtype]
|
117
|
+
# subclass.new(:text=>output, :file=>file.chomp(type)).convert(to, db, &yld)
|
118
|
+
# else
|
119
|
+
# subclass = Malt.registry[".#{to}"]
|
120
|
+
# subclass.new(:text=>output, :file=>refile(to), :fallback=>true)
|
121
|
+
# end
|
122
|
+
# end
|
123
|
+
|
124
|
+
# Produce a new filename replacing old extension with new
|
125
|
+
# extension.
|
126
|
+
#
|
127
|
+
# type - Symbol representation of extension (e.g. :html).
|
128
|
+
#
|
129
|
+
# Returns a String of the new file name.
|
130
|
+
def refile(type=nil)
|
131
|
+
if file
|
132
|
+
if type
|
133
|
+
type = type.to_s.sub(/^\./,'')
|
134
|
+
fext = self.class.extensions.find{|e| file.end_with?(e)}
|
135
|
+
new_file = file.chomp(fext) + type
|
136
|
+
else
|
137
|
+
fext = self.class.extensions.find{|e| file.end_with?(e)}
|
138
|
+
new_file = file.chomp('.'+fext)
|
139
|
+
end
|
140
|
+
else
|
141
|
+
new_file = nil
|
142
|
+
end
|
143
|
+
new_file
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
def extensions
|
148
|
+
self.class.extensions
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
def subtype
|
153
|
+
File.extname(file.chomp(type))
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
def to_s
|
158
|
+
text
|
159
|
+
end
|
160
|
+
|
161
|
+
# Default rendering type is +:html+. Override if it
|
162
|
+
# differs for the subclassing format.
|
163
|
+
def default
|
164
|
+
:html
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
def parse_type_and_data(type_and_data)
|
169
|
+
if Symbol === type_and_data.first
|
170
|
+
type = type_and_data.first
|
171
|
+
data = type_and_data.last
|
172
|
+
else
|
173
|
+
type = nil
|
174
|
+
data = type_and_data.first
|
175
|
+
end
|
176
|
+
return type, data
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
class UnsupportedConversion < Exception
|
183
|
+
def initialize(from_type, to_type)
|
184
|
+
@from_type = from_type
|
185
|
+
@to_type = to_type
|
186
|
+
super()
|
187
|
+
end
|
188
|
+
def message
|
189
|
+
"unsupported conversion: #{@from_type} -> #{@to_type}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'malt/formats/abstract'
|
2
|
+
|
3
|
+
module Malt::Formats
|
4
|
+
|
5
|
+
#
|
6
|
+
class CSS < Abstract
|
7
|
+
|
8
|
+
register('css')
|
9
|
+
|
10
|
+
#
|
11
|
+
def css(*)
|
12
|
+
text
|
13
|
+
end
|
14
|
+
|
15
|
+
# CSS is CSS ;)
|
16
|
+
def to_css(*)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
#
|
23
|
+
def render_engine
|
24
|
+
end
|
25
|
+
|
26
|
+
# CSS default output type is itself.
|
27
|
+
def default
|
28
|
+
:css
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'malt/formats/abstract_template'
|
2
|
+
require 'malt/formats/html'
|
3
|
+
require 'malt/engines/erb'
|
4
|
+
require 'malt/engines/erubis'
|
5
|
+
|
6
|
+
module Malt::Formats
|
7
|
+
|
8
|
+
#
|
9
|
+
class Erb < AbstractTemplate
|
10
|
+
|
11
|
+
register 'erb'
|
12
|
+
|
13
|
+
# TODO: Lookup engine from engine registry.
|
14
|
+
def rb(*)
|
15
|
+
render_engine.compile(:text=>text, :file=>file)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Erb templates can be "pre-compiled" into Ruby templates.
|
19
|
+
def to_rb(*)
|
20
|
+
text = rb
|
21
|
+
Ruby.new(:text=>text, :file=>refile(:rb))
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
alias_method(:to_ruby, :to_rb)
|
26
|
+
|
27
|
+
#
|
28
|
+
alias_method :precompile, :to_rb
|
29
|
+
|
30
|
+
# Technically #method_missing will pick this up, but since it is likely
|
31
|
+
# to be the most commonly used, adding the method directly will provide
|
32
|
+
# a small speed boost.
|
33
|
+
def html(data=nil, &yld)
|
34
|
+
render(:html, data, &yld)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Technically #method_missing will pick this up, but since it is likely
|
38
|
+
# to be the most commonly used, adding the method directly will provide
|
39
|
+
# a small speed boost.
|
40
|
+
def to_html(data=nil, &yld)
|
41
|
+
new_text = render(:html, data, &yld)
|
42
|
+
new_file = refile(:html)
|
43
|
+
new_options = options.merge(:text=>new_text, :file=>new_file, :type=>:html)
|
44
|
+
HTML.new(new_options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# #
|
48
|
+
# def to(type, data=nil, &yld)
|
49
|
+
# new_class = Malt.registry[type.to_sym]
|
50
|
+
# new_text = render(type, data, &yld)
|
51
|
+
# new_file = refile(type)
|
52
|
+
# new_options = options.merge(:text=>new_text, :file=>new_file, :type=>type)
|
53
|
+
# new_class.new(new_options)
|
54
|
+
# end
|
55
|
+
|
56
|
+
# #
|
57
|
+
# def render(*type_and_data, &yld)
|
58
|
+
# type, data = parse_type_and_data(type_and_data)
|
59
|
+
# opts = options.merge(:format=>type, :text=>text, :file=>file, :data=>data)
|
60
|
+
# #opts = options.merge(:format=>type, :text=>text, :file=>file, :data=>data, :engine=>engine)
|
61
|
+
# #Malt.render(opts, &yld)
|
62
|
+
# #if options[:recompile]
|
63
|
+
# render_engine.render(opts, &yld)
|
64
|
+
# #else
|
65
|
+
# # precompile.render(type, data, &yld)
|
66
|
+
# #end
|
67
|
+
# end
|
68
|
+
|
69
|
+
|
70
|
+
#
|
71
|
+
#def to_html(db, &yld)
|
72
|
+
# # unless pre-compilation is turned off, convert to ruby
|
73
|
+
# return to_ruby.to_html(db, &yld) unless options[:recompile]
|
74
|
+
# convert(:html, db, &yld)
|
75
|
+
#end
|
76
|
+
|
77
|
+
#
|
78
|
+
#def render_to(to, db, &yld)
|
79
|
+
# #if options[:recompile]
|
80
|
+
# render_engine.render(text, file, db, &yld)
|
81
|
+
# #else
|
82
|
+
# # to_ruby.render(db, &yld)
|
83
|
+
# #end
|
84
|
+
#end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
#
|
89
|
+
def render_engine
|
90
|
+
@render_engine ||= (
|
91
|
+
case engine
|
92
|
+
when :erubis
|
93
|
+
Malt::Engines::Erubis.new(options)
|
94
|
+
else
|
95
|
+
Malt::Engines::Erb.new(options)
|
96
|
+
end
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|