erector 0.9.0.pre1 → 0.9.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.
Files changed (60) hide show
  1. data/.gemtest +0 -0
  2. data/Gemfile +1 -1
  3. data/README.txt +3 -2
  4. data/Rakefile +39 -18
  5. data/VERSION.yml +1 -2
  6. data/bin/erector +6 -0
  7. data/lib/erector/abstract_widget.rb +15 -14
  8. data/lib/erector/caching.rb +2 -2
  9. data/lib/erector/convenience.rb +33 -1
  10. data/lib/erector/erect/erect.rb +2 -1
  11. data/lib/erector/externals.rb +10 -10
  12. data/lib/erector/html_widget.rb +1 -81
  13. data/lib/erector/needs.rb +3 -2
  14. data/lib/erector/rails/railtie.rb +2 -0
  15. data/lib/erector/rails3.rb +4 -1
  16. data/lib/erector/sass.rb +13 -2
  17. data/lib/erector/widget.rb +1 -1
  18. data/lib/erector/xml_widget.rb +2 -2
  19. data/spec/erector/convenience_spec.rb +4 -4
  20. data/spec/erector/needs_spec.rb +32 -13
  21. data/spec/erector/widget_spec.rb +11 -0
  22. data/spec/erector/xml_widget_spec.rb +2 -3
  23. data/spec/rails2/rails_app/Gemfile +2 -1
  24. data/spec/rails2/rails_app/Gemfile.lock +34 -31
  25. data/spec/rails2/rails_app/app/helpers/rails_helpers_spec_helper.rb +3 -0
  26. data/spec/rails2/rails_app/app/helpers/test_helper.rb +3 -0
  27. data/spec/rails2/rails_app/log/test.log +916 -2176
  28. data/spec/rails2/rails_app/spec/render_spec.rb +1 -1
  29. data/spec/rails_root/Gemfile +2 -1
  30. data/spec/rails_root/Gemfile.lock +126 -0
  31. data/spec/rails_root/app/views/layouts/widget_as_layout.rb +8 -0
  32. data/spec/rails_root/app/views/test/render_with_widget_as_layout.rb +5 -0
  33. data/spec/rails_root/app/views/test/render_with_widget_as_layout_using_content_for.rb +8 -0
  34. data/spec/rails_root/log/test.log +1974 -2147
  35. data/spec/rails_root/spec/rails_helpers_spec.rb +8 -0
  36. data/spec/rails_root/spec/render_spec.rb +29 -1
  37. data/spec/web/article_spec.rb +234 -0
  38. metadata +107 -76
  39. data/spec/rails2/rails_app/vendor/plugins/rails_xss/MIT-LICENSE +0 -20
  40. data/spec/rails2/rails_app/vendor/plugins/rails_xss/README.markdown +0 -90
  41. data/spec/rails2/rails_app/vendor/plugins/rails_xss/Rakefile +0 -23
  42. data/spec/rails2/rails_app/vendor/plugins/rails_xss/init.rb +0 -7
  43. data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss.rb +0 -3
  44. data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb +0 -87
  45. data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb +0 -33
  46. data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb +0 -52
  47. data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake +0 -4
  48. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/active_record_helper_test.rb +0 -74
  49. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb +0 -49
  50. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/caching_test.rb +0 -43
  51. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/date_helper_test.rb +0 -29
  52. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb +0 -112
  53. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/erb_util_test.rb +0 -36
  54. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/form_helper_test.rb +0 -1447
  55. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/form_tag_helper_test.rb +0 -354
  56. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/output_safety_test.rb +0 -115
  57. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/rails_xss_test.rb +0 -23
  58. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/test_helper.rb +0 -5
  59. data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/text_helper_test.rb +0 -17
  60. data/spec/rails_root/log/development.log +0 -17
File without changes
data/Gemfile CHANGED
@@ -12,7 +12,7 @@ group :development do
12
12
  gem "haml"
13
13
  gem "sass"
14
14
  gem "erubis"
15
- gem "rdoc", "~>2.3"
15
+ gem "rdoc", "~> 3.4"
16
16
  gem "wrong", ">=0.5.4"
17
17
  end
18
18
 
data/README.txt CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  * http://erector.rubyforge.org
4
4
  * mailto:erector@googlegroups.com
5
+ * http://github.com/pivotal/erector
5
6
  * http://www.pivotaltracker.com/projects/482
6
7
 
7
8
  == DESCRIPTION
@@ -44,8 +45,8 @@ check it out.
44
45
 
45
46
  == REQUIREMENTS
46
47
 
47
- The gem depends on rake and treetop, although this is just for using the command-line tool,
48
- so deployed applications won't need these. The Rails-dependent code is now separated so
48
+ The gem depends on rake and treetop, although this is just for using the command-line tool,
49
+ so deployed applications won't need these. The Rails-dependent code is now separated so
49
50
  you can use Erector cleanly in a non-Rails app.
50
51
 
51
52
  == INSTALL
data/Rakefile CHANGED
@@ -7,6 +7,9 @@ rescue LoadError
7
7
  warn "Couldn't find psych; continuing."
8
8
  end
9
9
 
10
+ require "bundler"
11
+ Bundler.setup
12
+
10
13
  require 'rake'
11
14
  require 'rake/testtask'
12
15
 
@@ -31,6 +34,7 @@ begin
31
34
  "VERSION.yml",
32
35
  "lib/**/*",
33
36
  "bin/erector",
37
+ ".gemtest",
34
38
  ]
35
39
  gemspec.executables = ["erector"]
36
40
  specs = Dir.glob("spec/**/*") #.reject { |file| file =~ %r{spec/rails2/} }
@@ -50,6 +54,7 @@ begin
50
54
  end
51
55
 
52
56
  Jeweler::RubyforgeTasks.new do |rubyforge|
57
+ rubyforge.project = "erector"
53
58
  rubyforge.doc_task = "rdoc"
54
59
  rubyforge.remote_doc_path = "rdoc"
55
60
  end
@@ -69,7 +74,9 @@ end
69
74
 
70
75
  desc "Build the web site from the .rb files in web/"
71
76
  task :web do
72
- files = Dir["web/*.rb"] - ["web/page.rb", "web/sidebar.rb", "web/clickable_li.rb"]
77
+ files = Dir["web/*.rb"].select do |filename|
78
+ File.read(filename) =~ (/\< Page/)
79
+ end
73
80
  require 'erector'
74
81
  require 'erector/erect/erect'
75
82
  $: << "."
@@ -85,11 +92,8 @@ task :clean_rdoc do
85
92
  FileUtils.rm_rf("rdoc")
86
93
  end
87
94
 
88
- # push the docs to Rubyforge
89
- task :publish_docs => :"rubyforge:release:docs"
90
-
91
- desc "Publish web site to RubyForge"
92
- task :publish_web do
95
+ desc "Publish web site and docs to RubyForge"
96
+ task :publish => [:web, :docs] do
93
97
  config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
94
98
  host = "#{config["username"]}@rubyforge.org"
95
99
  rubyforge_name = "erector"
@@ -98,19 +102,27 @@ task :publish_web do
98
102
  rdoc_dir = "rdoc"
99
103
  rsync_args = '--archive --verbose --delete'
100
104
 
105
+ puts "== Publishing web site to RubyForge"
101
106
  sh %{rsync #{rsync_args} --exclude=#{rdoc_dir} #{local_dir}/ #{host}:#{remote_dir}}
107
+
108
+ puts "== Publishing rdoc to RubyForge"
109
+ sh %{rsync #{rsync_args} #{rdoc_dir}/ #{host}:#{remote_dir}/rdoc}
102
110
  end
103
111
 
112
+
113
+ begin
104
114
  require 'rdoc/task'
105
- RDoc::Task.new(:rdoc) do |rdoc|
106
- rdoc.rdoc_dir = 'rdoc'
107
- rdoc.title = "Erector #{Erector::VERSION}"
108
- rdoc.options << '--inline-source' << "--promiscuous"
109
- rdoc.options << "--main=README.txt"
110
- # rdoc.options << '--diagram' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/ and not ENV['NODOT']
111
- rdoc.rdoc_files.include('README.txt')
112
- rdoc.rdoc_files.include('lib/**/*.rb')
113
- rdoc.rdoc_files.include('bin/**/*')
115
+ RDoc::Task.new(:rdoc) do |rdoc|
116
+ rdoc.rdoc_dir = 'rdoc'
117
+ rdoc.title = "Erector #{Erector::VERSION}"
118
+ rdoc.options <<
119
+ "--main=README.txt"
120
+ rdoc.rdoc_files.include('README.txt')
121
+ rdoc.rdoc_files.include('lib/**/*.rb')
122
+ rdoc.rdoc_files.include('bin/**/*')
123
+ end
124
+ rescue LoadError => e
125
+ puts "#{e.class}: #{e.message}"
114
126
  end
115
127
 
116
128
  desc "Regenerate unicode.rb from UnicodeData.txt from unicode.org. Only needs to be run when there is a new version of the Unicode specification"
@@ -146,6 +158,7 @@ namespace :spec do
146
158
  spec.pattern = 'spec/erect/*_spec.rb'
147
159
  end
148
160
 
161
+
149
162
  desc "Run specs for erector's Rails integration."
150
163
  RSpec::Core::RakeTask.new(:rails) do |spec|
151
164
  spec.pattern = 'spec/rails_root/spec/*_spec.rb'
@@ -153,9 +166,11 @@ namespace :spec do
153
166
 
154
167
  desc "Run specs for erector's Rails integration under Rails 2."
155
168
  task :rails2 do
156
- Dir.chdir("spec/rails2/rails_app") do
169
+ rails_app = "#{here}/spec/rails2/rails_app"
170
+ gemfile = "#{rails_app}/Gemfile"
171
+ Dir.chdir(rails_app) do
157
172
  # Bundler.with_clean_env do
158
- sh "BUNDLE_GEMFILE='./Gemfile' bundle exec rake rails2"
173
+ sh "BUNDLE_GEMFILE='#{gemfile}' bundle exec rake rails2"
159
174
  # end
160
175
  end
161
176
  end
@@ -165,7 +180,13 @@ namespace :spec do
165
180
  gemfile = "#{here}/Gemfile-rails31"
166
181
  sh "BUNDLE_GEMFILE='#{gemfile}' bundle exec rake spec:core spec:erect spec:rails"
167
182
  end
183
+
184
+ desc "Run specs for the Erector web site."
185
+ RSpec::Core::RakeTask.new(:web) do |spec|
186
+ spec.pattern = 'spec/web/*_spec.rb'
187
+ end
188
+
168
189
  end
169
190
 
170
191
  desc "Run most specs"
171
- task :spec => ['spec:core', 'spec:erect', 'spec:rails', 'spec:rails2']
192
+ task :spec => ['spec:core', 'spec:erect', 'spec:rails', 'spec:rails2', 'spec:web']
@@ -1,5 +1,4 @@
1
- ---
1
+ ---
2
2
  :major: 0
3
3
  :minor: 9
4
4
  :patch: 0
5
- :build: pre1
@@ -1,5 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ here = File.expand_path(File.dirname(__FILE__))
4
+
5
+ if File.directory?("#{here}/../lib/erector")
6
+ $:.unshift "#{here}/../lib"
7
+ end
8
+
3
9
  begin
4
10
  require 'erector'
5
11
  rescue LoadError
@@ -85,12 +85,12 @@ module Erector
85
85
  # content_method_name:: in case you want to call a method other than
86
86
  # #content, pass its name in here.
87
87
  #
88
- def render(options = {})
89
- _render(options).to_s
88
+ def emit(options = {})
89
+ _emit(options).to_s
90
90
  end
91
91
 
92
- # alias for #render
93
- # @deprecated Please use {#render} instead
92
+ # alias for #emit
93
+ # @deprecated Please use {#emit} instead
94
94
  def to_s(*args)
95
95
  unless defined? @@already_warned_to_s
96
96
  $stderr.puts "Erector::Widget#to_s is deprecated. Please use #to_html instead. Called from #{caller.first}"
@@ -103,9 +103,9 @@ module Erector
103
103
  # #render / #to_html only it returns an array, for theoretical performance
104
104
  # improvements when using a Rack server (like Sinatra or Rails Metal).
105
105
  #
106
- # # Options: see #render
106
+ # # Options: see #emit
107
107
  def to_a(options = {})
108
- _render(options).to_a
108
+ _emit(options).to_a
109
109
  end
110
110
 
111
111
  # Template method which must be overridden by all widget subclasses.
@@ -142,7 +142,7 @@ module Erector
142
142
  # the second argument is a hash used to populate its instance variables.
143
143
  # If the first argument is an instance then the hash must be unspecified
144
144
  # (or empty). If a block is passed to this method, then it gets set as the
145
- # rendered widget's block, and will be executed when that widget calls
145
+ # emited widget's block, and will be executed when that widget calls
146
146
  # +call_block+ or calls +super+ from inside its +content+ method.
147
147
  #
148
148
  # This is the preferred way to call one widget from inside another. This
@@ -150,12 +150,12 @@ module Erector
150
150
  # performance than using +capture+ or +to_html+.
151
151
  def widget(target, assigns = {}, options = {}, &block)
152
152
  if target.is_a? Class
153
- target.new(assigns, &block)._render_via(self, options)
153
+ target.new(assigns, &block)._emit_via(self, options)
154
154
  else
155
155
  unless assigns.empty?
156
156
  raise "Unexpected second parameter. Did you mean to pass in assigns when you instantiated the #{target.class.to_s}?"
157
157
  end
158
- target._render_via(self, options, &block)
158
+ target._emit_via(self, options, &block)
159
159
  end
160
160
  end
161
161
 
@@ -163,7 +163,7 @@ module Erector
163
163
  # output string to a string and returns it as raw text. If at all possible
164
164
  # you should avoid this method since it hurts performance, and use
165
165
  # +widget+ instead.
166
- def capture
166
+ def capture_content
167
167
  original, @_output = output, Output.new
168
168
  yield
169
169
  original.widgets.concat(output.widgets) # todo: test!!!
@@ -171,11 +171,12 @@ module Erector
171
171
  ensure
172
172
  @_output = original
173
173
  end
174
+ alias_method :capture, :capture_content
174
175
 
175
176
  protected
176
177
  # executes this widget's #content method, which emits stuff onto the
177
178
  # output stream
178
- def _render(options = {}, &block)
179
+ def _emit(options = {}, &block)
179
180
  @_block = block if block
180
181
  @_parent = options[:parent] || parent
181
182
  @_helpers = options[:helpers] || parent
@@ -195,9 +196,9 @@ module Erector
195
196
  output
196
197
  end
197
198
 
198
- # same as _render, but using a parent widget's output stream and helpers
199
- def _render_via(parent, options = {}, &block)
200
- _render(options.merge(:parent => parent,
199
+ # same as _emit, but using a parent widget's output stream and helpers
200
+ def _emit_via(parent, options = {}, &block)
201
+ _emit(options.merge(:parent => parent,
201
202
  :output => parent.output,
202
203
  :helpers => parent.helpers), &block)
203
204
  end
@@ -74,7 +74,7 @@ module Erector
74
74
  end
75
75
 
76
76
  protected
77
- def _render(options = {})
77
+ def _emit(options = {})
78
78
  if should_cache?
79
79
  cache[self.class, assigns, options[:content_method_name]] ||= super
80
80
  else
@@ -82,7 +82,7 @@ protected
82
82
  end
83
83
  end
84
84
 
85
- def _render_via(parent, options = {})
85
+ def _emit_via(parent, options = {})
86
86
  if should_cache?
87
87
  parent.output << cache[self.class, assigns, options[:content_method_name]] ||= parent.capture { super }
88
88
  parent.output.widgets << self.class # todo: test!!!
@@ -4,7 +4,7 @@ module Erector
4
4
  # You may just want to call to_html(:prettyprint => true)
5
5
  # so you can pass in other rendering options as well.
6
6
  def to_pretty(options = {})
7
- render(options.merge(:prettyprint => true))
7
+ emit(options.merge(:prettyprint => true))
8
8
  end
9
9
 
10
10
  # Render (like to_html) but stripping all tags and inserting some
@@ -57,6 +57,38 @@ module Erector
57
57
  a href, ({:href => href}.merge(options))
58
58
  end
59
59
 
60
+ # Emits a javascript block inside a +script+ tag, wrapped in CDATA
61
+ # doohickeys like all the cool JS kids do.
62
+ def javascript(value = nil, attributes = {})
63
+ if value.is_a?(Hash)
64
+ attributes = value
65
+ value = nil
66
+ elsif block_given? && value
67
+ raise ArgumentError, "You can't pass both a block and a value to javascript -- please choose one."
68
+ end
69
+
70
+ script(attributes.merge(:type => "text/javascript")) do
71
+ # Shouldn't this be a "cdata" HtmlPart?
72
+ # (maybe, but the syntax is specific to javascript; it isn't
73
+ # really a generic XML CDATA section. Specifically,
74
+ # ]]> within value is not treated as ending the
75
+ # CDATA section by Firefox2 when parsing text/html,
76
+ # although I guess we could refuse to generate ]]>
77
+ # there, for the benefit of XML/XHTML parsers).
78
+ output << raw("\n// <![CDATA[\n")
79
+ if block_given?
80
+ yield
81
+ else
82
+ output << raw(value)
83
+ end
84
+ output << raw("\n// ]]>")
85
+ output.append_newline # this forces a newline even if we're not in pretty mode
86
+ end
87
+
88
+ output << raw("\n")
89
+ end
90
+
91
+
60
92
  # makes a unique id based on the widget's class name and object id
61
93
  # that you can use as the HTML id of an emitted element
62
94
  def dom_id
@@ -1,5 +1,6 @@
1
1
  require "optparse"
2
2
  require "erector/erect/erected" # pull this out so we don't recreate the grammar every time
3
+ require "fileutils"
3
4
 
4
5
  module Erector
5
6
 
@@ -129,7 +130,7 @@ module Erector
129
130
  widget = widget_class.new
130
131
  #todo: skip if it's missing a no-arg constructor
131
132
  dir = output_dir || File.dirname(file)
132
- FileUtils.mkdir_p(dir)
133
+ ::FileUtils.mkdir_p(dir)
133
134
  output_file = "#{dir}/#{filename}.html"
134
135
  File.open(output_file, "w") do |f|
135
136
  f.puts widget.to_html
@@ -2,8 +2,8 @@ module Erector
2
2
 
3
3
  # Externals are a mechanism by which a widget can declare page-level
4
4
  # resources upon which it depends. They are not emitted during the widget's
5
- # normal rendering process. Rather, the Erector::Widget::Page keeps track of
6
- # all the widgets it renders, then goes back and inserts the proper tags for
5
+ # normal emiting process. Rather, the Erector::Widget::Page keeps track of
6
+ # all the widgets it emits, then goes back and inserts the proper tags for
7
7
  # all the externals inside its HEAD element.
8
8
  module Externals
9
9
  def self.included(base)
@@ -83,21 +83,21 @@ module Erector
83
83
  end
84
84
  end
85
85
 
86
- def render_with_externals(options_to_external_renderer = {})
86
+ def render_with_externals(options_to_external_emiter = {})
87
87
  output = Erector::Output.new
88
- self.to_a(:output => output) # render all the externals onto this new output buffer
88
+ self.to_a(:output => output) # emit all the externals onto this new output buffer
89
89
  nested_widgets = output.widgets.to_a
90
- options_to_external_renderer = {:classes => nested_widgets}.merge(options_to_external_renderer)
91
- renderer = ExternalRenderer.new(options_to_external_renderer)
92
- externals = renderer.to_a(:output => output)
90
+ options_to_external_emiter = {:classes => nested_widgets}.merge(options_to_external_emiter)
91
+ emiter = ExternalRenderer.new(options_to_external_emiter)
92
+ externals = emiter.to_a(:output => output)
93
93
  output.to_a
94
94
  end
95
95
 
96
- def render_externals(options_to_external_renderer = {})
96
+ def render_externals(options_to_external_emiter = {})
97
97
  output_for_externals = Erector::Output.new
98
98
  nested_widgets = output.widgets
99
- externalizer = ExternalRenderer.new({:classes => nested_widgets}.merge(options_to_external_renderer))
100
- externalizer._render(:output => output_for_externals)
99
+ externalizer = ExternalRenderer.new({:classes => nested_widgets}.merge(options_to_external_emiter))
100
+ externalizer._emit(:output => output_for_externals)
101
101
  output_for_externals.to_a
102
102
  end
103
103
  end
@@ -61,7 +61,7 @@ module Erector
61
61
  include Erector::HTML
62
62
  include Erector::Convenience
63
63
  include Erector::JQuery
64
- include Erector::Sass if Object.const_defined?(:Sass)
64
+ include Erector::Sass
65
65
 
66
66
  tag 'area', :self_closing
67
67
  tag 'base', :self_closing
@@ -194,39 +194,6 @@ module Erector
194
194
  tag 'video'
195
195
 
196
196
 
197
- # Emits a javascript block inside a +script+ tag, wrapped in CDATA
198
- # doohickeys like all the cool JS kids do.
199
- def javascript(value = nil, attributes = {})
200
- if value.is_a?(Hash)
201
- attributes = value
202
- value = nil
203
- elsif block_given? && value
204
- raise ArgumentError, "You can't pass both a block and a value to javascript -- please choose one."
205
- end
206
-
207
- script(attributes.merge(:type => "text/javascript")) do
208
- # Shouldn't this be a "cdata" HtmlPart?
209
- # (maybe, but the syntax is specific to javascript; it isn't
210
- # really a generic XML CDATA section. Specifically,
211
- # ]]> within value is not treated as ending the
212
- # CDATA section by Firefox2 when parsing text/html,
213
- # although I guess we could refuse to generate ]]>
214
- # there, for the benefit of XML/XHTML parsers).
215
- output << raw("\n// <![CDATA[\n")
216
- if block_given?
217
- yield
218
- else
219
- output << raw(value)
220
- end
221
- output << raw("\n// ]]>")
222
- output.append_newline # this forces a newline even if we're not in pretty mode
223
- end
224
-
225
- output << raw("\n")
226
- end
227
-
228
-
229
-
230
197
  # alias for AbstractWidget#render
231
198
  def to_html(options = {})
232
199
  raise "Erector::Widget#to_html takes an options hash, not a symbol. Try calling \"to_html(:content_method_name=> :#{options})\"" if options.is_a? Symbol
@@ -243,53 +210,6 @@ module Erector
243
210
  to_html(*args)
244
211
  end
245
212
 
246
-
247
- # Emits an XML instruction, which looks like this: <?xml version=\"1.0\" encoding=\"UTF-8\"?>
248
- def instruct(attributes={:version => "1.0", :encoding => "UTF-8"})
249
- output << raw("<?xml#{format_sorted(sort_for_xml_declaration(attributes))}?>")
250
- end
251
-
252
- # Emits an XML/HTML comment (&lt;!-- ... --&gt;) surrounding +text+ and/or
253
- # the output of +block+. see
254
- # http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.4
255
- #
256
- # If +text+ is an Internet Explorer conditional comment condition such as
257
- # "[if IE]", the output includes the opening condition and closing
258
- # "[endif]". See http://www.quirksmode.org/css/condcom.html
259
- #
260
- # Since "Authors should avoid putting two or more adjacent hyphens inside
261
- # comments," we emit a warning if you do that.
262
- def comment(text = '')
263
- puts "Warning: Authors should avoid putting two or more adjacent hyphens inside comments." if text =~ /--/
264
-
265
- conditional = text =~ /\[if .*\]/
266
-
267
- rawtext "<!--"
268
- rawtext text
269
- rawtext ">" if conditional
270
-
271
- if block_given?
272
- rawtext "\n"
273
- yield
274
- rawtext "\n"
275
- end
276
-
277
- rawtext "<![endif]" if conditional
278
- rawtext "-->\n"
279
- end
280
-
281
- protected
282
-
283
- def sort_for_xml_declaration(attributes)
284
- # correct order is "version, encoding, standalone" (XML 1.0 section 2.8).
285
- # But we only try to put version before encoding for now.
286
- stringized = []
287
- attributes.each do |key, value|
288
- stringized << [key.to_s, value]
289
- end
290
- stringized.sort{|a, b| b <=> a}
291
- end
292
-
293
213
  end
294
214
 
295
215
  public