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,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
|