haml 1.5.2 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/MIT-LICENSE +1 -1
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/css2sass +7 -0
- data/bin/html2haml +0 -82
- data/lib/haml.rb +43 -6
- data/lib/haml/buffer.rb +81 -72
- data/lib/haml/engine.rb +240 -110
- data/lib/haml/exec.rb +120 -5
- data/lib/haml/helpers.rb +88 -3
- data/lib/haml/helpers/action_view_extensions.rb +45 -0
- data/lib/haml/helpers/action_view_mods.rb +30 -17
- data/lib/haml/html.rb +173 -0
- data/lib/haml/template.rb +1 -26
- data/lib/haml/util.rb +18 -0
- data/lib/sass.rb +181 -3
- data/lib/sass/constant.rb +38 -9
- data/lib/sass/constant/color.rb +25 -1
- data/lib/sass/constant/literal.rb +10 -8
- data/lib/sass/css.rb +197 -0
- data/lib/sass/engine.rb +239 -68
- data/lib/sass/error.rb +2 -2
- data/lib/sass/plugin.rb +11 -3
- data/lib/sass/tree/attr_node.rb +25 -17
- data/lib/sass/tree/comment_node.rb +14 -0
- data/lib/sass/tree/node.rb +18 -1
- data/lib/sass/tree/rule_node.rb +17 -5
- data/lib/sass/tree/value_node.rb +4 -0
- data/test/haml/engine_test.rb +42 -25
- data/test/haml/helper_test.rb +28 -3
- data/test/haml/results/eval_suppressed.xhtml +6 -0
- data/test/haml/results/helpers.xhtml +26 -2
- data/test/haml/results/helpful.xhtml +2 -0
- data/test/haml/results/just_stuff.xhtml +17 -2
- data/test/haml/results/standard.xhtml +1 -1
- data/test/haml/results/whitespace_handling.xhtml +1 -11
- data/test/haml/rhtml/standard.rhtml +1 -1
- data/test/haml/template_test.rb +7 -2
- data/test/haml/templates/eval_suppressed.haml +7 -2
- data/test/haml/templates/helpers.haml +16 -1
- data/test/haml/templates/helpful.haml +2 -0
- data/test/haml/templates/just_stuff.haml +23 -4
- data/test/haml/templates/standard.haml +3 -3
- data/test/haml/templates/whitespace_handling.haml +0 -50
- data/test/sass/engine_test.rb +35 -10
- data/test/sass/plugin_test.rb +10 -6
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/complex.css +4 -3
- data/test/sass/results/constants.css +3 -3
- data/test/sass/results/import.css +27 -0
- data/test/sass/results/nested.css +7 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +1 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/complex.sass +19 -1
- data/test/sass/templates/constants.sass +8 -0
- data/test/sass/templates/import.sass +8 -0
- data/test/sass/templates/importee.sass +10 -0
- data/test/sass/templates/nested.sass +8 -0
- data/test/sass/templates/parent_ref.sass +25 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- metadata +95 -75
- data/test/haml/results/semantic.cache +0 -15
data/lib/haml/exec.rb
CHANGED
@@ -16,12 +16,28 @@ module Haml
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def parse!
|
19
|
-
|
20
|
-
|
19
|
+
begin
|
20
|
+
@opts = OptionParser.new(&(method(:set_opts).to_proc))
|
21
|
+
@opts.parse!(@args)
|
21
22
|
|
22
|
-
|
23
|
+
process_result
|
24
|
+
|
25
|
+
@options
|
26
|
+
rescue Exception => e
|
27
|
+
raise e if e.is_a? SystemExit
|
23
28
|
|
24
|
-
|
29
|
+
line = e.backtrace[0].scan(/:(.*)/)[0]
|
30
|
+
puts "#{e.class} on line #{line}: #{e.message}"
|
31
|
+
|
32
|
+
if @options[:trace]
|
33
|
+
e.backtrace[1..-1].each { |t| puts " #{t}" }
|
34
|
+
else
|
35
|
+
puts " Use --trace to see traceback"
|
36
|
+
end
|
37
|
+
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
exit 0
|
25
41
|
end
|
26
42
|
|
27
43
|
def to_s
|
@@ -39,6 +55,15 @@ module Haml
|
|
39
55
|
@options[:output] = $stdout
|
40
56
|
end
|
41
57
|
|
58
|
+
opts.on('-s', '--stdio', 'Read input from standard input and print output to standard output') do
|
59
|
+
@options[:input] = $stdin
|
60
|
+
@options[:output] = $stdout
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.on('--trace', :NONE, 'Show a full traceback on error') do
|
64
|
+
@options[:trace] = true
|
65
|
+
end
|
66
|
+
|
42
67
|
opts.on_tail("-?", "-h", "--help", "Show this message") do
|
43
68
|
puts opts
|
44
69
|
exit
|
@@ -102,6 +127,47 @@ Description:
|
|
102
127
|
Options:
|
103
128
|
END
|
104
129
|
|
130
|
+
opts.on('--rails RAILS_DIR', "Install Haml from the Gem to a Rails project") do |dir|
|
131
|
+
original_dir = dir
|
132
|
+
|
133
|
+
dir = File.join(dir, 'vendor', 'plugins')
|
134
|
+
|
135
|
+
unless File.exists?(dir)
|
136
|
+
puts "Directory #{dir} doesn't exist"
|
137
|
+
exit
|
138
|
+
end
|
139
|
+
|
140
|
+
dir = File.join(dir, 'haml')
|
141
|
+
|
142
|
+
if File.exists?(dir)
|
143
|
+
puts "Directory #{dir} already exists."
|
144
|
+
exit
|
145
|
+
end
|
146
|
+
|
147
|
+
begin
|
148
|
+
Dir.mkdir(dir)
|
149
|
+
rescue SystemCallError
|
150
|
+
puts "Cannot create #{dir}"
|
151
|
+
exit
|
152
|
+
end
|
153
|
+
|
154
|
+
File.open(File.join(dir, 'init.rb'), 'w') do |file|
|
155
|
+
file.puts <<END
|
156
|
+
require 'rubygems'
|
157
|
+
require 'haml'
|
158
|
+
require 'haml/template'
|
159
|
+
require 'sass'
|
160
|
+
require 'sass/plugin'
|
161
|
+
|
162
|
+
ActionView::Base.register_template_handler('haml', Haml::Template)
|
163
|
+
Sass::Plugin.update_stylesheets
|
164
|
+
END
|
165
|
+
end
|
166
|
+
|
167
|
+
puts "Haml plugin added to #{original_dir}"
|
168
|
+
exit
|
169
|
+
end
|
170
|
+
|
105
171
|
super
|
106
172
|
end
|
107
173
|
|
@@ -156,12 +222,61 @@ END
|
|
156
222
|
# A class encapsulating executable functionality
|
157
223
|
# specific to the html2haml executable.
|
158
224
|
class HTML2Haml < Generic # :nodoc:
|
225
|
+
def initialize(args)
|
226
|
+
super
|
227
|
+
|
228
|
+
@module_opts = {}
|
229
|
+
|
230
|
+
begin
|
231
|
+
require 'haml/html'
|
232
|
+
rescue LoadError => err
|
233
|
+
dep = err.message.scan(/^no such file to load -- (.*)/)[0]
|
234
|
+
puts "Required dependency #{dep} not found!"
|
235
|
+
exit 1
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
159
239
|
def set_opts(opts)
|
160
240
|
opts.banner = <<END
|
161
241
|
Usage: html2haml [options] (html file) (output file)
|
162
242
|
|
163
243
|
Description: Transforms an HTML file into corresponding Haml code.
|
164
244
|
|
245
|
+
Options:
|
246
|
+
END
|
247
|
+
|
248
|
+
opts.on('-r', '--rhtml', 'Parse RHTML tags.') do
|
249
|
+
@module_opts[:rhtml] = true
|
250
|
+
end
|
251
|
+
|
252
|
+
super
|
253
|
+
end
|
254
|
+
|
255
|
+
def process_result
|
256
|
+
super
|
257
|
+
|
258
|
+
input = @options[:input]
|
259
|
+
output = @options[:output]
|
260
|
+
|
261
|
+
output.write(::Haml::HTML.new(input, @module_opts).render)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# A class encapsulating executable functionality
|
266
|
+
# specific to the css2sass executable.
|
267
|
+
class CSS2Sass < Generic # :nodoc:
|
268
|
+
def initialize(args)
|
269
|
+
super
|
270
|
+
|
271
|
+
require 'sass/css'
|
272
|
+
end
|
273
|
+
|
274
|
+
def set_opts(opts)
|
275
|
+
opts.banner = <<END
|
276
|
+
Usage: css2sass [options] (css file) (output file)
|
277
|
+
|
278
|
+
Description: Transforms a CSS file into corresponding Sass code.
|
279
|
+
|
165
280
|
Options:
|
166
281
|
END
|
167
282
|
|
@@ -174,7 +289,7 @@ END
|
|
174
289
|
input = @options[:input]
|
175
290
|
output = @options[:output]
|
176
291
|
|
177
|
-
output.write(
|
292
|
+
output.write(::Sass::CSS.new(input).render)
|
178
293
|
end
|
179
294
|
end
|
180
295
|
end
|
data/lib/haml/helpers.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'haml/helpers/action_view_mods'
|
2
|
+
require 'haml/helpers/action_view_extensions'
|
2
3
|
|
3
4
|
module Haml
|
4
5
|
# This module contains various helpful methods to make it easier to do
|
@@ -7,7 +8,7 @@ module Haml
|
|
7
8
|
# disposal from within the template.
|
8
9
|
module Helpers
|
9
10
|
self.extend self
|
10
|
-
|
11
|
+
|
11
12
|
@@action_view_defined = defined?(ActionView)
|
12
13
|
@@force_no_action_view = false
|
13
14
|
|
@@ -83,6 +84,22 @@ module Haml
|
|
83
84
|
to_return.join("\n")
|
84
85
|
end
|
85
86
|
|
87
|
+
# Returns a hash containing default assignments for the xmlns and xml:lang
|
88
|
+
# attributes of the <tt>html</tt> HTML element.
|
89
|
+
# It also takes an optional argument for the value of xml:lang and lang,
|
90
|
+
# which defaults to 'en-US'.
|
91
|
+
# For example,
|
92
|
+
#
|
93
|
+
# %html{html_attrs}
|
94
|
+
#
|
95
|
+
# becomes
|
96
|
+
#
|
97
|
+
# <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-US' lang='en-US'>
|
98
|
+
#
|
99
|
+
def html_attrs(lang = 'en-US')
|
100
|
+
{:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang}
|
101
|
+
end
|
102
|
+
|
86
103
|
# Increments the number of tabs the buffer automatically adds
|
87
104
|
# to the lines of the template.
|
88
105
|
# For example:
|
@@ -184,6 +201,73 @@ module Haml
|
|
184
201
|
def capture_haml(*args, &block)
|
185
202
|
capture_haml_with_buffer(buffer.buffer, *args, &block)
|
186
203
|
end
|
204
|
+
|
205
|
+
# Outputs text directly to the Haml buffer, with the proper tabulation
|
206
|
+
def puts(text = "")
|
207
|
+
buffer.buffer << (' ' * buffer.tabulation) << text.to_s << "\n"
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
|
211
|
+
#
|
212
|
+
# call-seq:
|
213
|
+
# open(name, attributes = {}) {...}
|
214
|
+
# open(name, text, attributes = {}) {...}
|
215
|
+
#
|
216
|
+
# Creates an HTML tag with the given name and optionally text and attributes.
|
217
|
+
# Can take a block that will be executed
|
218
|
+
# between when the opening and closing tags are output.
|
219
|
+
# If the block is a Haml block or outputs text using puts,
|
220
|
+
# the text will be properly indented.
|
221
|
+
#
|
222
|
+
# For example,
|
223
|
+
#
|
224
|
+
# open :table do
|
225
|
+
# open :tr do
|
226
|
+
# open :td, {:class => 'cell'} do
|
227
|
+
# open :strong, "strong!"
|
228
|
+
# puts "data"
|
229
|
+
# end
|
230
|
+
# open :td do
|
231
|
+
# puts "more_data"
|
232
|
+
# end
|
233
|
+
# end
|
234
|
+
# end
|
235
|
+
#
|
236
|
+
# outputs
|
237
|
+
#
|
238
|
+
# <table>
|
239
|
+
# <tr>
|
240
|
+
# <td class='cell'>
|
241
|
+
# <strong>
|
242
|
+
# strong!
|
243
|
+
# </strong>
|
244
|
+
# data
|
245
|
+
# </td>
|
246
|
+
# <td>
|
247
|
+
# more_data
|
248
|
+
# </td>
|
249
|
+
# </tr>
|
250
|
+
# </table>
|
251
|
+
#
|
252
|
+
def open(name, attributes = {}, alt_atts = {}, &block)
|
253
|
+
text = nil
|
254
|
+
if attributes.is_a? String
|
255
|
+
text = attributes
|
256
|
+
attributes = alt_atts
|
257
|
+
end
|
258
|
+
|
259
|
+
puts "<#{name}#{buffer.build_attributes(attributes)}>"
|
260
|
+
tab_up
|
261
|
+
# Print out either the text (using push_text) or call the block and add an endline
|
262
|
+
if text
|
263
|
+
puts(text)
|
264
|
+
elsif block
|
265
|
+
block.call
|
266
|
+
end
|
267
|
+
tab_down
|
268
|
+
puts "</#{name}>"
|
269
|
+
nil
|
270
|
+
end
|
187
271
|
|
188
272
|
private
|
189
273
|
|
@@ -205,7 +289,7 @@ module Haml
|
|
205
289
|
def capture_haml_with_buffer(local_buffer, *args, &block)
|
206
290
|
position = local_buffer.length
|
207
291
|
|
208
|
-
block.call
|
292
|
+
block.call *args
|
209
293
|
|
210
294
|
captured = local_buffer.slice!(position..-1)
|
211
295
|
|
@@ -221,7 +305,6 @@ module Haml
|
|
221
305
|
end
|
222
306
|
result.to_s
|
223
307
|
end
|
224
|
-
alias_method :capture_erb_with_buffer, :capture_haml_with_buffer
|
225
308
|
|
226
309
|
# Returns whether or not the current template is a Haml template.
|
227
310
|
#
|
@@ -231,6 +314,8 @@ module Haml
|
|
231
314
|
def is_haml?
|
232
315
|
@haml_is_haml
|
233
316
|
end
|
317
|
+
|
318
|
+
include ActionViewExtensions if self.const_defined? "ActionViewExtensions"
|
234
319
|
end
|
235
320
|
end
|
236
321
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'haml/helpers/action_view_mods'
|
2
|
+
|
3
|
+
if defined?(ActionView)
|
4
|
+
module Haml
|
5
|
+
module Helpers
|
6
|
+
# This module contains various useful helper methods
|
7
|
+
# that either tie into ActionView or the rest of the ActionPack stack,
|
8
|
+
# or are only useful in that context.
|
9
|
+
# Thus, the methods defined here are only available
|
10
|
+
# if ActionView is installed.
|
11
|
+
module ActionViewExtensions
|
12
|
+
# Returns a value for the "class" attribute
|
13
|
+
# unique to this controller/action pair.
|
14
|
+
# This can be used to target styles specifically at this action or controller.
|
15
|
+
# For example, if the current action were EntryController#show,
|
16
|
+
#
|
17
|
+
# %div{:class => page_class} My Div
|
18
|
+
#
|
19
|
+
# would become
|
20
|
+
#
|
21
|
+
# <div class="entry show">My Div</div>
|
22
|
+
#
|
23
|
+
# Then, in a stylesheet
|
24
|
+
# (shown here as Sass),
|
25
|
+
# you could refer to this specific action:
|
26
|
+
#
|
27
|
+
# .entry.show
|
28
|
+
# :font-weight bold
|
29
|
+
#
|
30
|
+
# or to all actions in the entry controller:
|
31
|
+
#
|
32
|
+
# .entry
|
33
|
+
# :color #00f
|
34
|
+
#
|
35
|
+
def page_class
|
36
|
+
controller.controller_name + " " + controller.action_name
|
37
|
+
end
|
38
|
+
|
39
|
+
# :stopdoc:
|
40
|
+
alias_method :generate_content_class_names, :page_class
|
41
|
+
# :startdoc:
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -8,7 +8,7 @@ rescue LoadError
|
|
8
8
|
action_view_included = false
|
9
9
|
end
|
10
10
|
|
11
|
-
if action_view_included
|
11
|
+
if action_view_included
|
12
12
|
module ActionView
|
13
13
|
class Base # :nodoc:
|
14
14
|
def render_with_haml(*args)
|
@@ -26,6 +26,18 @@ if action_view_included
|
|
26
26
|
# to make them work more effectively with Haml.
|
27
27
|
module Helpers
|
28
28
|
# :stopdoc:
|
29
|
+
module CaptureHelper
|
30
|
+
def capture_erb_with_buffer_with_haml(*args, &block)
|
31
|
+
if is_haml?
|
32
|
+
capture_haml_with_buffer(*args, &block)
|
33
|
+
else
|
34
|
+
capture_erb_with_buffer_without_haml(*args, &block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
alias_method :capture_erb_with_buffer_without_haml, :capture_erb_with_buffer
|
38
|
+
alias_method :capture_erb_with_buffer, :capture_erb_with_buffer_with_haml
|
39
|
+
end
|
40
|
+
|
29
41
|
module TextHelper
|
30
42
|
def concat_with_haml(string, binding = nil)
|
31
43
|
if is_haml?
|
@@ -37,26 +49,30 @@ if action_view_included
|
|
37
49
|
alias_method :concat_without_haml, :concat
|
38
50
|
alias_method :concat, :concat_with_haml
|
39
51
|
end
|
40
|
-
|
52
|
+
|
41
53
|
module FormTagHelper
|
42
54
|
def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
|
43
|
-
if
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
if is_haml?
|
56
|
+
if block_given?
|
57
|
+
oldproc = proc
|
58
|
+
proc = bind_proc do |*args|
|
59
|
+
concat "\n"
|
60
|
+
tab_up
|
61
|
+
oldproc.call(*args)
|
62
|
+
tab_down
|
63
|
+
end
|
50
64
|
end
|
65
|
+
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
|
66
|
+
concat "\n" if block_given? && is_haml?
|
67
|
+
res
|
68
|
+
else
|
69
|
+
form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
|
51
70
|
end
|
52
|
-
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
|
53
|
-
concat "\n" if block_given? && is_haml?
|
54
|
-
res
|
55
71
|
end
|
56
72
|
alias_method :form_tag_without_haml, :form_tag
|
57
73
|
alias_method :form_tag, :form_tag_with_haml
|
58
74
|
end
|
59
|
-
|
75
|
+
|
60
76
|
module FormHelper
|
61
77
|
def form_for_with_haml(object_name, *args, &proc)
|
62
78
|
if block_given? && is_haml?
|
@@ -73,11 +89,8 @@ if action_view_included
|
|
73
89
|
alias_method :form_for_without_haml, :form_for
|
74
90
|
alias_method :form_for, :form_for_with_haml
|
75
91
|
end
|
76
|
-
|
77
|
-
def generate_content_class_names
|
78
|
-
controller.controller_name + " " + controller.action_name
|
79
|
-
end
|
80
92
|
# :startdoc:
|
81
93
|
end
|
82
94
|
end
|
83
95
|
end
|
96
|
+
|
data/lib/haml/html.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../haml'
|
2
|
+
|
3
|
+
require 'haml/engine'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'hpricot'
|
6
|
+
require 'cgi'
|
7
|
+
|
8
|
+
module Haml
|
9
|
+
# This class contains the functionality used in the +html2haml+ utility,
|
10
|
+
# namely converting HTML documents to Haml templates.
|
11
|
+
# It depends on Hpricot for HTML parsing (http://code.whytheluckystiff.net/hpricot/).
|
12
|
+
class HTML
|
13
|
+
# Creates a new instance of Haml::HTML that will compile the given template,
|
14
|
+
# which can either be a string containing HTML or an Hpricot node,
|
15
|
+
# to a Haml string when +render+ is called.
|
16
|
+
def initialize(template, options = {})
|
17
|
+
@@options = options
|
18
|
+
|
19
|
+
if template.is_a? Hpricot::Node
|
20
|
+
@template = template
|
21
|
+
else
|
22
|
+
if template.is_a? IO
|
23
|
+
template = template.read
|
24
|
+
end
|
25
|
+
|
26
|
+
if @@options[:rhtml]
|
27
|
+
match_to_html(template, /<%=(.*?)-?%>/m, 'loud')
|
28
|
+
match_to_html(template, /<%(.*?)-?%>/m, 'silent')
|
29
|
+
end
|
30
|
+
@template = Hpricot(template)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Processes the document and returns the result as a string
|
35
|
+
# containing the Haml template.
|
36
|
+
def render
|
37
|
+
@template.to_haml(0)
|
38
|
+
end
|
39
|
+
alias_method :to_haml, :render
|
40
|
+
|
41
|
+
module ::Hpricot::Node
|
42
|
+
# Returns the Haml representation of the given node,
|
43
|
+
# at the given tabulation.
|
44
|
+
def to_haml(tabs = 0)
|
45
|
+
parse_text(self.to_s, tabs)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def tabulate(tabs)
|
51
|
+
' ' * tabs
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_text(text, tabs)
|
55
|
+
text.strip!
|
56
|
+
if text.empty?
|
57
|
+
String.new
|
58
|
+
else
|
59
|
+
lines = text.split("\n")
|
60
|
+
|
61
|
+
lines.map do |line|
|
62
|
+
line.strip!
|
63
|
+
"#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
|
64
|
+
end.join
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# :stopdoc:
|
70
|
+
|
71
|
+
def self.options
|
72
|
+
@@options
|
73
|
+
end
|
74
|
+
|
75
|
+
TEXT_REGEXP = /^(\s*).*$/
|
76
|
+
|
77
|
+
class ::Hpricot::Doc
|
78
|
+
def to_haml(tabs = 0)
|
79
|
+
output = ''
|
80
|
+
children.each { |child| output += child.to_haml(0) }
|
81
|
+
output
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class ::Hpricot::XMLDecl
|
86
|
+
def to_haml(tabs = 0)
|
87
|
+
"#{tabulate(tabs)}!!! XML\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class ::Hpricot::DocType
|
92
|
+
def to_haml(tabs = 0)
|
93
|
+
attrs = public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
|
94
|
+
if attrs == nil
|
95
|
+
raise Exception.new("Invalid doctype")
|
96
|
+
end
|
97
|
+
|
98
|
+
type, version, strictness = attrs.map { |a| a.downcase }
|
99
|
+
if type == "html"
|
100
|
+
version = "1.0"
|
101
|
+
strictness = "transitional"
|
102
|
+
end
|
103
|
+
|
104
|
+
if version == "1.0" || version.empty?
|
105
|
+
version = nil
|
106
|
+
end
|
107
|
+
|
108
|
+
if strictness == 'transitional' || strictness.empty?
|
109
|
+
strictness = nil
|
110
|
+
end
|
111
|
+
|
112
|
+
version = " #{version}" if version
|
113
|
+
if strictness
|
114
|
+
strictness[0] = strictness[0] - 32
|
115
|
+
strictness = " #{strictness}"
|
116
|
+
end
|
117
|
+
|
118
|
+
"#{tabulate(tabs)}!!!#{version}#{strictness}\n"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class ::Hpricot::Comment
|
123
|
+
def to_haml(tabs = 0)
|
124
|
+
"#{tabulate(tabs)}/\n#{parse_text(self.content, tabs + 1)}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class ::Hpricot::Elem
|
129
|
+
def to_haml(tabs = 0)
|
130
|
+
output = "#{tabulate(tabs)}"
|
131
|
+
if HTML.options[:rhtml] && name[0...5] == 'haml:'
|
132
|
+
return output + HTML.send("haml_tag_#{name[5..-1]}", self.innerHTML)
|
133
|
+
end
|
134
|
+
|
135
|
+
output += "%#{name}" unless name == 'div' && (attributes.include?('id') || attributes.include?('class'))
|
136
|
+
|
137
|
+
if attributes
|
138
|
+
output += "##{attributes['id']}" if attributes['id']
|
139
|
+
attributes['class'].split(' ').each { |c| output += ".#{c}" } if attributes['class']
|
140
|
+
attributes.delete("id")
|
141
|
+
attributes.delete("class")
|
142
|
+
output += attributes.inspect if attributes.length > 0
|
143
|
+
end
|
144
|
+
|
145
|
+
output += "/" if children.length == 0
|
146
|
+
output += "\n"
|
147
|
+
|
148
|
+
self.children.each do |child|
|
149
|
+
output += child.to_haml(tabs + 1)
|
150
|
+
end
|
151
|
+
|
152
|
+
output
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.haml_tag_loud(text)
|
157
|
+
"= #{text.gsub(/\n\s*/, '; ').strip}\n"
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.haml_tag_silent(text)
|
161
|
+
text.split("\n").map { |line| "- #{line.strip}\n" }.join
|
162
|
+
end
|
163
|
+
|
164
|
+
private
|
165
|
+
|
166
|
+
def match_to_html(string, regex, tag)
|
167
|
+
string.gsub!(regex) do
|
168
|
+
"<haml:#{tag}>#{CGI.escapeHTML($1)}</haml:#{tag}>"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
# :startdoc:
|
172
|
+
end
|
173
|
+
end
|