malt 0.2.0 → 0.3.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 CHANGED
@@ -1,5 +1,24 @@
1
1
  = Release History
2
2
 
3
+
4
+ == 0.3.0 | 2010-11-04
5
+
6
+ New release adds a Malt::Machine class that encapsulates all
7
+ Malt's class level functionality. This allow Malt to be
8
+ be more finaly controlled. For example an instance of
9
+ Malt::Machine can be used to limit rendering to a select
10
+ set of formats.
11
+
12
+ Changes:
13
+
14
+ * Add Machine class to ecapsulate toplevel functions.
15
+ * Add feature via Machine options to select available formats.
16
+ * Add `#to_default` to for converting to default format.
17
+ * Add `Malt.engine?` to test for supported engine types.
18
+ * Rename `Malt.support?` to `Malt.format?`.
19
+ * Rename `Malt.main` to `Malt.cli`.
20
+
21
+
3
22
  == 0.2.0 | 2010-10-22
4
23
 
5
24
  Malt now support Erector, Markaby, Builder and Mustache templates.
data/License.txt CHANGED
@@ -1,4 +1,5 @@
1
1
  .
2
+
2
3
  Apache License
3
4
  Version 2.0, January 2004
4
5
  http://www.apache.org/licenses/
@@ -201,4 +202,4 @@
201
202
  See the License for the specific language governing permissions and
202
203
  limitations under the License.
203
204
 
204
-
205
+ .
data/README.rdoc CHANGED
@@ -18,7 +18,7 @@ very easy to implement thanks to it's clean design.
18
18
 
19
19
  === Functional API
20
20
 
21
- Malt.render(:file=>'foo.erb', :format=>:html, :data=>data)
21
+ Malt.render(:file=>'foo.erb', :to=>:html, :data=>data)
22
22
 
23
23
  Where +data+ is a data source of some type. Malt will see
24
24
  that the file is an ERB template and render it accordingly.
data/bin/malt CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'malt'
3
- Malt.main(*ARGV)
3
+ Malt.cli(*ARGV)
4
4
 
data/lib/malt.rb CHANGED
@@ -1,5 +1,7 @@
1
+ require 'malt/meta/data'
1
2
  require 'malt/kernel'
2
- require 'malt/render'
3
+ require 'malt/machine'
4
+ require 'malt/core_ext'
3
5
 
4
6
  module Malt
5
7
 
@@ -8,60 +10,42 @@ module Malt
8
10
  end
9
11
 
10
12
  #
11
- def self.register(malt_class, *exts)
12
- exts.each do |ext|
13
- type = ext_to_type(ext)
14
- registry[type] = malt_class
15
- end
13
+ def self.machine
14
+ @machine ||= Machine.new
16
15
  end
17
16
 
18
17
  #
19
- def self.registry
20
- @registry ||= {}
18
+ def self.file(file, options={})
19
+ machine.file(file, options)
21
20
  end
22
21
 
23
22
  #
24
- def self.support?(ext)
25
- ext = ext.to_s
26
- type = ext.sub(/^\./, '').strip
27
- return false if type.empty?
28
- #@registry.key?(ext.to_sym)
29
- #Engine.registry[type.to_sym]
30
- Engine.registry.key?(type.to_sym)
23
+ def self.text(text, options={})
24
+ machine.text(text, options)
31
25
  end
32
26
 
33
27
  #
34
- def self.file(file, options={})
35
- type = options[:type] || options[:format] || File.extname(file)
36
- type = ext_to_type(type)
37
- malt_class = registry[type]
38
- raise "unkown type -- #{type}" unless malt_class
39
- malt_class.new(options.merge(:file=>file,:type=>type))
28
+ def self.open(url, options={})
29
+ machine.open(url, options)
40
30
  end
41
31
 
42
32
  #
43
- def self.text(text, options={})
44
- if file = options[:file]
45
- ext = File.extname(file)
46
- ext = nil if ext.empty?
47
- end
48
- type = options[:type] || options[:format] || ext
49
- type = ext_to_type(type)
50
- malt_class = registry[type] || Format::Text
51
- #raise "unkown type -- #{type}" unless malt_class
52
- malt_class.new(options.merge(:text=>text,:file=>file,:type=>type))
33
+ def self.render(params, &body)
34
+ machine.render(params, &body)
53
35
  end
54
36
 
55
37
  #
56
- def self.open(url, options={})
57
- require 'open-uri'
58
- text = open(url).read
59
- file = File.basename(url) # parse better with URI.parse
60
- text(text, :file=>file)
38
+ def self.format?(ext)
39
+ machine.format?(ext)
40
+ end
41
+
42
+ # Returns true if the extension given is renderable.
43
+ def self.engine?(ext)
44
+ machine.engine?(ext)
61
45
  end
62
46
 
63
47
  #
64
- def self.main(*args)
48
+ def self.cli(*args)
65
49
  require 'optparse'
66
50
  itype, otype = nil, nil
67
51
  OptionParser.new{|o|
@@ -22,6 +22,10 @@ module Engine
22
22
  @registry ||= {}
23
23
  end
24
24
 
25
+ #
26
+ def self.defaults
27
+ @defaults ||= {}
28
+ end
25
29
 
26
30
  # Abstract Template class serves as the base
27
31
  # class for all other Template classes.
@@ -38,10 +42,15 @@ module Engine
38
42
  def self.default(*exts)
39
43
  register(*exts)
40
44
  exts.each do |ext|
41
- Malt.config.engine[ext.to_sym] = self
45
+ Engine.defaults[ext.to_sym] = self
42
46
  end
43
47
  end
44
48
 
49
+ #
50
+ def self.type
51
+ basename.downcase.to_sym
52
+ end
53
+
45
54
  #
46
55
  def initialize(settings={})
47
56
  @settings = settings.rekey
@@ -3,6 +3,23 @@ require 'malt/kernel'
3
3
  module Malt
4
4
  module Format
5
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] = malt_class
15
+ end
16
+ end
17
+
18
+ #
19
+ def self.registry
20
+ @registry ||= {}
21
+ end
22
+
6
23
  # Abstract format class serves as the base
7
24
  # class for all other format classes.
8
25
  #
@@ -12,7 +29,7 @@ module Format
12
29
  # Register the class to an extension type.
13
30
  def self.register(*exts)
14
31
  @extensions = exts
15
- Malt.register(self, *exts)
32
+ Malt::Format.register(self, *exts)
16
33
 
17
34
  #exts.each do |ext|
18
35
  # Abstract.module_eval %{
@@ -10,7 +10,7 @@ module Format
10
10
 
11
11
  #
12
12
  def to(type, data=nil, &yld)
13
- new_class = Malt.registry[type.to_sym]
13
+ new_class = Malt::Format.registry[type.to_sym] # TODO: Malt.machine.format?
14
14
  new_text = render(type, data, &yld)
15
15
  new_file = refile(type)
16
16
  new_options = options.merge(:text=>new_text, :file=>new_file, :type=>type)
@@ -28,11 +28,11 @@ module Format
28
28
 
29
29
  # ERB templates can be any type.
30
30
  def method_missing(sym, *args, &yld)
31
- if Malt.registry.key?(sym)
31
+ if Malt::Format.registry.key?(sym) # TODO: Malt.machine.format?
32
32
  return render(sym, *args, &yld).to_s
33
33
  elsif md = /^to_/.match(sym.to_s)
34
34
  type = md.post_match.to_sym
35
- if Malt.registry.key?(type)
35
+ if Malt::Format.registry.key?(type) # TODO: Malt.machine.format?
36
36
  return to(type, *args, &yld)
37
37
  end
38
38
  end
@@ -29,7 +29,7 @@ module Malt::Format
29
29
 
30
30
  #
31
31
  def to(type, data=nil, &yld)
32
- new_class = Malt.registry[type.to_sym]
32
+ new_class = Malt::Format.registry[type.to_sym] # TODO: Malt.machine.format?
33
33
  new_text = render(data, &yld)
34
34
  new_file = refile(type)
35
35
  new_options = options.merge(:text=>new_text, :file=>new_file)
@@ -38,11 +38,11 @@ module Malt::Format
38
38
 
39
39
  # Ruby templates can be any type.
40
40
  def method_missing(sym, *args, &yld)
41
- if Malt.registry.key?(sym)
41
+ if Malt::Format.registry.key?(sym)
42
42
  return to(sym, *args, &yld).to_s
43
43
  elsif md = /^to_/.match(sym.to_s)
44
44
  type = md.post_match.to_sym
45
- if Malt.registry.key?(type)
45
+ if Malt::Format.registry.key?(type) # TODO: Malt.machine.format?
46
46
  return to(type, *args, &yld)
47
47
  end
48
48
  end
@@ -0,0 +1,227 @@
1
+ module Malt
2
+
3
+ # The Machine class encapsulates Malt's main methods
4
+ # along with configuratable settings to control
5
+ # which engines and formats are used for rendering.
6
+ #--
7
+ # TODO: Can we dynamically generate the MARKUP and TEMPLATE constants
8
+ # from the format classes? In anycase, the still need tweaking.
9
+ #++
10
+ class Machine
11
+
12
+ # List of markup types. These are formats that just allow markup transformations
13
+ # and do not provide for data injection.
14
+ MARKUP = [:rdoc, :markdown, :textile, :scss, :sass, :less, :css, :html, :xml]
15
+
16
+ # List of template types. These are template formats that provide data injection.
17
+ TEMPLATES = [:ruby, :erb, :liquid, :mustache, :tenjin, :ragtag, :radius, :erector, :builder, :markaby]
18
+
19
+ # Template types that prevent arbitrary Ruby code execution.
20
+ TEMPLATES_SAFE = [:liquid, :mustache]
21
+
22
+ # New Malt Machine.
23
+ #
24
+ # * config[:types] - list of formats to handle
25
+ # * config[:priority] - list of prioritized engines
26
+ #
27
+ def initialize(config={})
28
+ if priority = config[:priority]
29
+ priority.map!{ |e| e.to_sym }
30
+ else
31
+ priority = []
32
+ end
33
+ if types = config[:types] || config[:type]
34
+ formats = {}
35
+ engines = {}
36
+ types.each do |type|
37
+ k = ext_to_type(type)
38
+ formats[k] = Malt::Format.registry[k]
39
+ engines[k] = Malt::Engine.registry[k]
40
+ end
41
+ else
42
+ formats = Malt::Format.registry #.dup
43
+ engines = Malt::Engine.registry #.dup
44
+ end
45
+ @formats = formats
46
+ @engines = engines
47
+ @priority = priority
48
+ end
49
+
50
+ #
51
+ def formats
52
+ @formats
53
+ end
54
+
55
+ #
56
+ def engines
57
+ @engines
58
+ end
59
+
60
+ # Engine priorities.
61
+ #
62
+ # Returns an Array of symbolic engine names.
63
+ def priority(type=nil)
64
+ if type
65
+ type = type.to_s.downcase.to_sym
66
+ @priority.unshift(type)
67
+ @priority.uniq! # assuming first are kept
68
+ end
69
+ @priority
70
+ end
71
+
72
+ #
73
+ def engine?(ext)
74
+ type = ext_to_type(ext)
75
+ engines.key?(type)
76
+ ##ext = ext.to_s
77
+ ##type = ext.sub(/^\./, '').strip
78
+ ##return false if type.empty?
79
+ ###@registry.key?(ext.to_sym)
80
+ ###Engine.registry[type.to_sym]
81
+ ##Engine.registry.key?(type.to_sym)
82
+ end
83
+
84
+ #
85
+ def format?(ext)
86
+ type = ext_to_type(ext)
87
+ formats.key?(type)
88
+ end
89
+
90
+ #
91
+ def file(file, options={})
92
+ type = options[:type] || options[:format] || File.extname(file)
93
+ type = ext_to_type(type)
94
+ malt_class = formats[type]
95
+ raise "unkown type -- #{type}" unless malt_class
96
+ malt_class.new(options.merge(:file=>file,:type=>type))
97
+ end
98
+
99
+ #
100
+ def text(text, options={})
101
+ if file = options[:file]
102
+ ext = File.extname(file)
103
+ ext = nil if ext.empty?
104
+ end
105
+ type = options[:type] || options[:format] || ext
106
+ type = ext_to_type(type)
107
+ malt_class = formats[type] || Format::Text # :pass ?
108
+ #raise "unkown type -- #{type}" unless malt_class
109
+ malt_class.new(options.merge(:text=>text,:file=>file,:type=>type))
110
+ end
111
+
112
+ # Open a URL as a Malt Format object.
113
+ def open(url, options={})
114
+ require 'open-uri'
115
+ text = open(url).read
116
+ file = File.basename(url) # parse better with URI.parse
117
+ text(text, :file=>file)
118
+ end
119
+
120
+ # Render template directly.
121
+ #
122
+ # parameters[:file] - File name of template. Used to read text.
123
+ # parameters[:text] - Text of template document.
124
+ # parameters[:type] - File type/extension used to look up engine.
125
+ # parameters[:pass] - If not a supported type return text rather than raise an error.
126
+ # parameters[:engine] - Force the use of a this specific engine.
127
+ # parameters[:to] - Format to convert to (usual default is `html`).
128
+ #
129
+ def render(parameters={}, &body)
130
+ type = parameters[:type]
131
+ file = parameters[:file]
132
+ text = parameters[:text]
133
+ engine = parameters[:engine]
134
+
135
+ type = file_type(file, type)
136
+ text = file_read(file) unless text
137
+
138
+ engine_class = engine(type, engine)
139
+
140
+ if engine_class
141
+ parameters[:type] = type
142
+ parameters[:text] = text
143
+
144
+ engine = engine_class.new
145
+ engine.render(parameters, &body)
146
+ else
147
+ if parameters[:pass]
148
+ text
149
+ else
150
+ raise NoEngineError, "no engine to handle `#{type}' format"
151
+ end
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ #
158
+ def engine(type, engine=nil)
159
+ type = ext_to_type(type)
160
+ #engine = engine || Malt.config.engine[type] # FIXME
161
+ case engine
162
+ when Class
163
+ #raise unless Engine.registry[type].include?(engine)
164
+ engine
165
+ when String, Symbol
166
+ match = engine.to_s.downcase.to_sym
167
+ #Engine.registry[type].find{ |e| e.basename.downcase == match }
168
+ #engines[type].find{ |e| e.basename.downcase == match }
169
+ engines[type].find{ |e| match == e.type }
170
+ else
171
+ if engines[type]
172
+ #Engine.registry[type].first
173
+ types = engines[type]
174
+ if prior = types.find{ |e| priority.include?(e.type) }
175
+ return prior
176
+ end
177
+ if default = Engine.defaults[type]
178
+ return default #if engine?(default.type)
179
+ end
180
+ types.first
181
+ else
182
+ nil
183
+ end
184
+ end
185
+ end
186
+
187
+ #
188
+ def file_type(file, type=nil)
189
+ ext = type || File.extname(file)
190
+ ext = ext.to_s.downcase
191
+ if ext.empty?
192
+ nil
193
+ elsif ext[0,1] == '.'
194
+ ext[1..-1].to_sym
195
+ else
196
+ ext.to_sym
197
+ end
198
+ end
199
+
200
+ #
201
+ #def ext_type(type)
202
+ # type.to_s.downcase.sub(/^\./,'').to_sym
203
+ #end
204
+
205
+ # TODO: Handle File objects and URLs.
206
+ def file_read(file)
207
+ File.read(file)
208
+ end
209
+
210
+ # Normal file extension to a symbol type reference.
211
+ def ext_to_type(ext)
212
+ ext = ext.to_s.downcase
213
+ return nil if ext.empty?
214
+ if ext[0,1] == '.'
215
+ ext[1..-1].to_sym
216
+ else
217
+ ext.to_sym
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ #
224
+ class NoEngineError < ArgumentError
225
+ end
226
+
227
+ end
@@ -1,6 +1,6 @@
1
1
  name : malt
2
- date : 2010-10-22
3
- version : 0.2.0
2
+ date : 2010-11-04
3
+ version : 0.3.0
4
4
 
5
5
  requires:
6
6
  - syckle (build)
data/meta/package CHANGED
@@ -1,6 +1,6 @@
1
1
  name : malt
2
- date : 2010-10-22
3
- version : 0.2.0
2
+ date : 2010-11-04
3
+ version : 0.3.0
4
4
 
5
5
  requires:
6
6
  - syckle (build)
@@ -0,0 +1,29 @@
1
+ == Limited Formats
2
+
3
+ The Machine class makes it possible to control which formats
4
+ are available for rendering.
5
+
6
+ For example, let's make a Machine that only support RDoc format
7
+ and no others.
8
+
9
+ malt = Malt::Machine.new(:types=>[:rdoc])
10
+
11
+ Now we use the `malt` machine object to handle rendering. First let's
12
+ make sure that the machine is infact setup to limit formats to just RDoc.
13
+
14
+ malt.formats.keys.assert = [:rdoc]
15
+
16
+ malt.assert.format?('.rdoc')
17
+ malt.refute.format?('.markdown')
18
+
19
+ This being the case we should be able to render an RDoc file without issue.
20
+
21
+ malt.render(:file=>'qed/samples/sample.rdoc')
22
+
23
+ Where as another format type, though usually supported, but excluded in this
24
+ case, will fail.
25
+
26
+ expect Malt::NoEngineError do
27
+ malt.render(:file=>'qed/samples/sample.markdown')
28
+ end
29
+
@@ -0,0 +1,34 @@
1
+ == Prioritized Engines
2
+
3
+ The Malt Machine class can also be used to prioritize engines.
4
+ For instance, by default markdown documents are handled by
5
+ the RDiscount library.
6
+
7
+ malt = Malt::Machine.new
8
+
9
+ engine = malt.pry.engine(:markdown)
10
+ engine.assert == Malt::Engine::RDiscount
11
+
12
+ To use Kramdown instead, we can specify
13
+ it as a priority when initilizeing a new Machine.
14
+
15
+ malt = Malt::Machine.new(:priority=>[:kramdown])
16
+
17
+ Lets check to make sure.
18
+
19
+ engine = malt.pry.engine(:markdown)
20
+ engine.assert == Malt::Engine::Kramdown
21
+
22
+ To change the engine priorities of the master Malt Machine, provide
23
+ the #priority method with the type and it will put it at the top of
24
+ the priority list.
25
+
26
+ Malt.machine.priority :kramdown
27
+
28
+ Lets check to make sure.
29
+
30
+ engine = Malt.machine.pry.engine(:markdown)
31
+ engine.assert == Malt::Engine::Kramdown
32
+
33
+ (If you are wondering, #pry is simply used to call a private method.)
34
+
data/qed/applique/malt.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'malt'
2
+ require 'ae/pry'
2
3
 
3
4
  When "say we have a (((\\w+))) document called '(((\\S+)))' containing" do |type, fname, text|
4
5
  file = File.join('tmp',fname)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: malt
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Thomas Sawyer
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-28 00:00:00 -04:00
18
+ date: 2010-11-04 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -247,7 +247,6 @@ files:
247
247
  - features/step_definitions/engine_steps.rb
248
248
  - features/support/loadpath.rb
249
249
  - features/support/sample_class.rb
250
- - lib/malt/config.rb
251
250
  - lib/malt/core_ext.rb
252
251
  - lib/malt/engines/abstract.rb
253
252
  - lib/malt/engines/bluecloth.rb
@@ -300,11 +299,11 @@ files:
300
299
  - lib/malt/formats/yaml.rb
301
300
  - lib/malt/formats.rb
302
301
  - lib/malt/kernel.rb
302
+ - lib/malt/machine.rb
303
303
  - lib/malt/markup.rb
304
304
  - lib/malt/meta/data.rb
305
305
  - lib/malt/meta/package
306
306
  - lib/malt/meta/profile
307
- - lib/malt/render.rb
308
307
  - lib/malt/template.rb
309
308
  - lib/malt.rb
310
309
  - meta/data.rb
@@ -331,6 +330,8 @@ files:
331
330
  - qed/03_formats/18_builder.rb
332
331
  - qed/03_formats/19_erector.rb
333
332
  - qed/03_formats/20_mustache.rdoc
333
+ - qed/05_machine/01_limited_formats.rdoc
334
+ - qed/05_machine/02_prioritized_engines.rdoc
334
335
  - qed/applique/malt.rb
335
336
  - qed/samples/data.yml
336
337
  - qed/samples/output-erb.txt
data/lib/malt/config.rb DELETED
@@ -1,12 +0,0 @@
1
- module Malt
2
-
3
- class Config
4
-
5
- #
6
- def engine
7
- @engine ||= {}
8
- end
9
-
10
- end
11
-
12
- end
data/lib/malt/render.rb DELETED
@@ -1,93 +0,0 @@
1
- require 'malt/kernel'
2
- require 'malt/config'
3
- require 'malt/core_ext'
4
-
5
- module Malt
6
-
7
- extend Kernel
8
-
9
- #
10
- def self.config
11
- @config ||= Config.new
12
- end
13
-
14
- # Render template.
15
- #
16
- # parameters[:file] - File name of template. Used to read text.
17
- # parameters[:text] - Text of template document.
18
- # parameters[:type] - File type/extension used to look up engine.
19
- # parameters[:pass] - If not a supported type return text rather than raise an error.
20
- # parameters[:engine] - Force the use of a this specific engine.
21
- # parameters[:to] - Format to convert to (usual default is `html`).
22
- #
23
- def self.render(parameters={}, &body)
24
- type = parameters[:type]
25
- file = parameters[:file]
26
- text = parameters[:text]
27
- engine = parameters[:engine]
28
-
29
- type = file_type(file, type)
30
- text = file_read(file) unless text
31
-
32
- engine_class = engine(type, engine)
33
-
34
- if engine_class
35
- parameters[:type] = type
36
- parameters[:text] = text
37
-
38
- engine = engine_class.new
39
- engine.render(parameters, &body)
40
- else
41
- if parameters[:pass]
42
- text
43
- else
44
- raise "no engine to handle `#{type}' format"
45
- end
46
- end
47
- end
48
-
49
- #
50
- def self.engine(type, engine=nil)
51
- type = ext_to_type(type)
52
- engine = engine || config.engine[type]
53
- case engine
54
- when Class
55
- #raise unless Engine.registry[type].include?(engine)
56
- engine
57
- when String, Symbol
58
- match = engine.to_s.downcase
59
- Engine.registry[type].find{ |e| e.basename.downcase == match }
60
- else
61
- if Engine.registry[type]
62
- Engine.registry[type].first
63
- else
64
- nil
65
- end
66
- end
67
- end
68
-
69
- #
70
- def self.file_type(file, type=nil)
71
- ext = type || File.extname(file)
72
- ext = ext.to_s.downcase
73
- if ext.empty?
74
- nil
75
- elsif ext[0,1] == '.'
76
- ext[1..-1].to_sym
77
- else
78
- ext.to_sym
79
- end
80
- end
81
-
82
- #
83
- #def self.ext_type(type)
84
- # type.to_s.downcase.sub(/^\./,'').to_sym
85
- #end
86
-
87
- # TODO: Handle File objects and URLs.
88
- def self.file_read(file)
89
- File.read(file)
90
- end
91
-
92
- end
93
-