haml 1.8.2 → 2.0.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.

Files changed (77) hide show
  1. data/FAQ +138 -0
  2. data/MIT-LICENSE +1 -1
  3. data/{README → README.rdoc} +66 -3
  4. data/Rakefile +111 -147
  5. data/VERSION +1 -1
  6. data/bin/css2sass +0 -0
  7. data/bin/haml +0 -0
  8. data/bin/html2haml +0 -0
  9. data/bin/sass +0 -0
  10. data/init.rb +6 -1
  11. data/lib/haml.rb +464 -201
  12. data/lib/haml/buffer.rb +117 -63
  13. data/lib/haml/engine.rb +63 -44
  14. data/lib/haml/error.rb +16 -6
  15. data/lib/haml/exec.rb +37 -7
  16. data/lib/haml/filters.rb +213 -68
  17. data/lib/haml/helpers.rb +95 -60
  18. data/lib/haml/helpers/action_view_extensions.rb +1 -1
  19. data/lib/haml/helpers/action_view_mods.rb +54 -6
  20. data/lib/haml/html.rb +6 -6
  21. data/lib/haml/precompiler.rb +254 -133
  22. data/lib/haml/template.rb +3 -6
  23. data/lib/haml/template/patch.rb +9 -2
  24. data/lib/haml/template/plugin.rb +52 -23
  25. data/lib/sass.rb +157 -12
  26. data/lib/sass/constant.rb +22 -22
  27. data/lib/sass/constant/color.rb +13 -13
  28. data/lib/sass/constant/literal.rb +7 -7
  29. data/lib/sass/constant/number.rb +9 -9
  30. data/lib/sass/constant/operation.rb +4 -4
  31. data/lib/sass/constant/string.rb +3 -3
  32. data/lib/sass/css.rb +104 -31
  33. data/lib/sass/engine.rb +120 -39
  34. data/lib/sass/error.rb +1 -1
  35. data/lib/sass/plugin.rb +14 -3
  36. data/lib/sass/plugin/merb.rb +6 -2
  37. data/lib/sass/tree/attr_node.rb +5 -5
  38. data/lib/sass/tree/directive_node.rb +2 -7
  39. data/lib/sass/tree/node.rb +1 -12
  40. data/lib/sass/tree/rule_node.rb +39 -31
  41. data/lib/sass/tree/value_node.rb +1 -1
  42. data/test/benchmark.rb +67 -80
  43. data/test/haml/engine_test.rb +284 -84
  44. data/test/haml/helper_test.rb +51 -15
  45. data/test/haml/results/content_for_layout.xhtml +1 -2
  46. data/test/haml/results/eval_suppressed.xhtml +2 -4
  47. data/test/haml/results/filters.xhtml +44 -15
  48. data/test/haml/results/helpers.xhtml +2 -3
  49. data/test/haml/results/just_stuff.xhtml +2 -6
  50. data/test/haml/results/nuke_inner_whitespace.xhtml +34 -0
  51. data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  52. data/test/haml/results/original_engine.xhtml +3 -7
  53. data/test/haml/results/partials.xhtml +1 -0
  54. data/test/haml/results/tag_parsing.xhtml +1 -6
  55. data/test/haml/results/very_basic.xhtml +2 -4
  56. data/test/haml/results/whitespace_handling.xhtml +13 -21
  57. data/test/haml/template_test.rb +8 -15
  58. data/test/haml/templates/_partial.haml +1 -0
  59. data/test/haml/templates/filters.haml +48 -7
  60. data/test/haml/templates/just_stuff.haml +1 -2
  61. data/test/haml/templates/nuke_inner_whitespace.haml +26 -0
  62. data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  63. data/test/haml/templates/tag_parsing.haml +0 -3
  64. data/test/haml/test_helper.rb +15 -0
  65. data/test/sass/engine_test.rb +80 -34
  66. data/test/sass/plugin_test.rb +1 -1
  67. data/test/sass/results/import.css +2 -2
  68. data/test/sass/results/mixins.css +95 -0
  69. data/test/sass/results/multiline.css +24 -0
  70. data/test/sass/templates/import.sass +4 -1
  71. data/test/sass/templates/importee.sass +4 -0
  72. data/test/sass/templates/mixins.sass +76 -0
  73. data/test/sass/templates/multiline.sass +20 -0
  74. metadata +65 -51
  75. data/lib/haml/util.rb +0 -18
  76. data/test/haml/runner.rb +0 -16
  77. data/test/profile.rb +0 -65
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.2
1
+ 2.0.0
File without changes
data/bin/haml CHANGED
File without changes
File without changes
data/bin/sass CHANGED
File without changes
data/init.rb CHANGED
@@ -1,2 +1,7 @@
1
- require 'haml'
1
+ begin
2
+ require File.join(File.dirname(__FILE__), 'lib', 'haml') # From here
3
+ rescue LoadError
4
+ require 'haml' # From gem
5
+ end
6
+
2
7
  Haml.init_rails(binding)
@@ -2,18 +2,18 @@ dir = File.dirname(__FILE__)
2
2
  $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
3
3
 
4
4
  # = Haml (XHTML Abstraction Markup Language)
5
- #
5
+ #
6
6
  # Haml is a markup language
7
7
  # that's used to cleanly and simply describe the XHTML of any web document,
8
8
  # without the use of inline code.
9
9
  # Haml functions as a replacement
10
- # for inline page templating systems such as PHP, ERB, and ASP.
11
- # However, Haml avoids the need for explicitly coding XHTML into the template,
10
+ # for inline page templating systems such as PHP, ERB, and ASP.
11
+ # However, Haml avoids the need for explicitly coding XHTML into the template,
12
12
  # because it is actually an abstract description of the XHTML,
13
13
  # with some code to generate dynamic content.
14
- #
14
+ #
15
15
  # == Features
16
- #
16
+ #
17
17
  # * Whitespace active
18
18
  # * Well-formatted markup
19
19
  # * DRY
@@ -36,9 +36,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
36
36
  #
37
37
  # To enable it as a Rails plugin,
38
38
  # then run
39
- #
39
+ #
40
40
  # haml --rails path/to/rails/app
41
- #
41
+ #
42
42
  # Haml is enabled in Merb by default,
43
43
  # so Merb users don't have to do anything more.
44
44
  #
@@ -50,24 +50,24 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
50
50
  # the same way you do in ERb templates.
51
51
  # Helper methods are also available in Haml templates.
52
52
  # For example (this example uses Rails, but the principle for Merb is the same):
53
- #
53
+ #
54
54
  # # file: app/controllers/movies_controller.rb
55
- #
55
+ #
56
56
  # class MoviesController < ApplicationController
57
57
  # def index
58
58
  # @title = "Teen Wolf"
59
59
  # end
60
60
  # end
61
- #
61
+ #
62
62
  # -# file: app/views/movies/index.haml
63
- #
63
+ #
64
64
  # #content
65
65
  # .title
66
66
  # %h1= @title
67
67
  # = link_to 'Home', home_url
68
- #
68
+ #
69
69
  # may be compiled to:
70
- #
70
+ #
71
71
  # <div id='content'>
72
72
  # <div class='title'>
73
73
  # <h1>Teen Wolf</h1>
@@ -89,41 +89,41 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
89
89
  # engine.render #=> "<p>Haml code!</p>\n"
90
90
  #
91
91
  # == Characters with meaning to Haml
92
- #
92
+ #
93
93
  # Various characters, when placed at a certain point in a line,
94
94
  # instruct Haml to render different types of things.
95
- #
95
+ #
96
96
  # === XHTML Tags
97
- #
97
+ #
98
98
  # These characters render XHTML tags.
99
- #
99
+ #
100
100
  # ==== %
101
- #
102
- #
101
+ #
102
+ #
103
103
  # The percent character is placed at the beginning of a line.
104
104
  # It's followed immediately by the name of an element,
105
105
  # then optionally by modifiers (see below), a space,
106
106
  # and text to be rendered inside the element.
107
107
  # It creates an element in the form of <tt><element></element></tt>.
108
108
  # For example:
109
- #
109
+ #
110
110
  # %one
111
111
  # %two
112
112
  # %three Hey there
113
- #
113
+ #
114
114
  # is compiled to:
115
- #
115
+ #
116
116
  # <one>
117
117
  # <two>
118
118
  # <three>Hey there</three>
119
119
  # </two>
120
120
  # </one>
121
- #
121
+ #
122
122
  # Any string is a valid element name;
123
123
  # Haml will automatically generate opening and closing tags for any element.
124
- #
124
+ #
125
125
  # ==== {}
126
- #
126
+ #
127
127
  # Brackets represent a Ruby hash
128
128
  # that is used for specifying the attributes of an element.
129
129
  # It is literally evaluated as a Ruby hash,
@@ -132,18 +132,20 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
132
132
  # will be replaced by appropriate escape sequences.
133
133
  # The hash is placed after the tag is defined.
134
134
  # For example:
135
- #
135
+ #
136
136
  # %head{ :name => "doc_head" }
137
137
  # %script{ 'type' => "text/" + "javascript",
138
138
  # :src => "javascripts/script_#{2 + 7}" }
139
- #
139
+ #
140
140
  # is compiled to:
141
- #
141
+ #
142
142
  # <head name="doc_head">
143
143
  # <script src='javascripts/script_9' type='text/javascript'>
144
144
  # </script>
145
145
  # </head>
146
146
  #
147
+ # ===== Attribute Methods
148
+ #
147
149
  # A Ruby method call that returns a hash
148
150
  # can be substituted for the hash contents.
149
151
  # For example, Haml::Helpers defines the following method:
@@ -182,9 +184,36 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
182
184
  # would compile to:
183
185
  #
184
186
  # <sandwich bread='whole wheat' delicious='true' filling='peanut butter and jelly' />
185
- #
187
+ #
188
+ # ===== Boolean Attributes
189
+ #
190
+ # Some attributes, such as "checked" for <tt>input</tt> tags or "selected" for <tt>option</tt> tags,
191
+ # are "boolean" in the sense that their values don't matter -
192
+ # it only matters whether or not they're present.
193
+ # In HTML (but not XHTML), these attributes can be written as
194
+ #
195
+ # <input selected>
196
+ #
197
+ # To do this in Haml, just assign a Ruby true value to the attribute:
198
+ #
199
+ # %input{:selected => true}
200
+ #
201
+ # In XHTML, the only valid value for these attributes is the name of the attribute.
202
+ # Thus this will render in XHTML as
203
+ #
204
+ # <input selected="selected">
205
+ #
206
+ # To set these attributes to false, simply assign them to a Ruby false value.
207
+ # In both XHTML and HTML
208
+ #
209
+ # %input{:selected => false}
210
+ #
211
+ # will just render as
212
+ #
213
+ # <input>
214
+ #
186
215
  # ==== []
187
- #
216
+ #
188
217
  # Square brackets follow a tag definition and contain a Ruby object
189
218
  # that is used to set the class and id of that tag.
190
219
  # The class is set to the object's class
@@ -192,41 +221,40 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
192
221
  # and the id is set to the object's class, followed by its id.
193
222
  # Because the id of an object is normally an obscure implementation detail,
194
223
  # this is most useful for elements that represent instances of Models.
224
+ # Additionally, the second argument (if present) will be used as a prefix for
225
+ # both the id and class attributes.
195
226
  # For example:
196
- #
227
+ #
197
228
  # # file: app/controllers/users_controller.rb
198
- #
229
+ #
199
230
  # def show
200
231
  # @user = CrazyUser.find(15)
201
232
  # end
202
- #
233
+ #
203
234
  # -# file: app/views/users/show.haml
204
- #
205
- # %div[@user]
235
+ #
236
+ # %div[@user, :greeting]
206
237
  # %bar[290]/
207
238
  # Hello!
208
- #
239
+ #
209
240
  # is compiled to:
210
- #
211
- # <div class="crazy_user" id="crazy_user_15">
241
+ #
242
+ # <div class="greeting_crazy_user" id="greeting_crazy_user_15">
212
243
  # <bar class="fixnum" id="fixnum_581" />
213
244
  # Hello!
214
245
  # </div>
215
- #
216
- # This is based off of DHH's SimplyHelpful syntax,
217
- # as presented at RailsConf Europe 2006.
218
- #
246
+ #
219
247
  # ==== /
220
- #
248
+ #
221
249
  # The forward slash character, when placed at the end of a tag definition,
222
250
  # causes the tag to be self-closed.
223
251
  # For example:
224
- #
252
+ #
225
253
  # %br/
226
254
  # %meta{'http-equiv' => 'Content-Type', :content => 'text/html'}/
227
- #
255
+ #
228
256
  # is compiled to:
229
- #
257
+ #
230
258
  # <br />
231
259
  # <meta http-equiv='Content-Type' content='text/html' />
232
260
  #
@@ -242,9 +270,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
242
270
  #
243
271
  # <br />
244
272
  # <meta http-equiv='Content-Type' content='text/html' />
245
- #
273
+ #
246
274
  # ==== . and #
247
- #
275
+ #
248
276
  # The period and pound sign are borrowed from CSS.
249
277
  # They are used as shortcuts to specify the <tt>class</tt>
250
278
  # and <tt>id</tt> attributes of an element, respectively.
@@ -252,22 +280,22 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
252
280
  # by chaining the class names together with periods.
253
281
  # They are placed immediately after the tag and before an attributes hash.
254
282
  # For example:
255
- #
283
+ #
256
284
  # %div#things
257
285
  # %span#rice Chicken Fried
258
286
  # %p.beans{ :food => 'true' } The magical fruit
259
287
  # %h1.class.otherclass#id La La La
260
- #
288
+ #
261
289
  # is compiled to:
262
- #
290
+ #
263
291
  # <div id='things'>
264
292
  # <span id='rice'>Chicken Fried</span>
265
293
  # <p class='beans' food='true'>The magical fruit</p>
266
294
  # <h1 class='class otherclass' id='id'>La La La</h1>
267
295
  # </div>
268
- #
296
+ #
269
297
  # And,
270
- #
298
+ #
271
299
  # #content
272
300
  # .articles
273
301
  # .article.title
@@ -276,9 +304,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
276
304
  # 2006-11-05
277
305
  # .article.entry
278
306
  # Neil Patrick Harris would like to dispel any rumors that he is straight
279
- #
307
+ #
280
308
  # is compiled to:
281
- #
309
+ #
282
310
  # <div id="content">
283
311
  # <div class="articles">
284
312
  # <div class="article title">Doogie Howser Comes Out</div>
@@ -288,34 +316,89 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
288
316
  # </div>
289
317
  # </div>
290
318
  # </div>
291
- #
319
+ #
292
320
  # ==== Implicit Div Elements
293
- #
321
+ #
294
322
  # Because the div element is used so often, it is the default element.
295
323
  # If you only define a class and/or id using the <tt>.</tt> or <tt>#</tt> syntax,
296
324
  # a div element is automatically used.
297
325
  # For example:
298
- #
326
+ #
299
327
  # #collection
300
328
  # .item
301
329
  # .description What a cool item!
302
- #
330
+ #
303
331
  # is the same as:
304
- #
332
+ #
305
333
  # %div{:id => collection}
306
334
  # %div{:class => 'item'}
307
335
  # %div{:class => 'description'} What a cool item!
308
- #
336
+ #
309
337
  # and is compiled to:
310
- #
338
+ #
311
339
  # <div id='collection'>
312
340
  # <div class='item'>
313
341
  # <div class='description'>What a cool item!</div>
314
342
  # </div>
315
343
  # </div>
316
- #
344
+ #
345
+ # ==== > and <
346
+ #
347
+ # <tt>></tt> and <tt><</tt> give you more control over the whitespace near a tag.
348
+ # <tt>></tt> will remove all whitespace surrounding a tag,
349
+ # while <tt><</tt> will remove all whitespace immediately within a tag.
350
+ # You can think of them as alligators eating the whitespace:
351
+ # <tt>></tt> faces out of the tag and eats the whitespace on the outside,
352
+ # and <tt><</tt> faces into the tag and eats the whitespace on the inside.
353
+ # They're placed at the end of a tag definition,
354
+ # after class, id, and attribute declarations
355
+ # but before <tt>/</tt> or <tt>=</tt>.
356
+ # For example:
357
+ #
358
+ # %blockquote<
359
+ # %div
360
+ # Foo!
361
+ #
362
+ # is compiled to:
363
+ #
364
+ # <blockquote><div>
365
+ # Foo!
366
+ # </div></blockquote>
367
+ #
368
+ # And:
369
+ #
370
+ # %img
371
+ # %img>
372
+ # %img
373
+ #
374
+ # is compiled to:
375
+ #
376
+ # <img /><img /><img />
377
+ #
378
+ # And:
379
+ #
380
+ # %p<= "Foo\nBar"
381
+ #
382
+ # is compiled to:
383
+ #
384
+ # <p>Foo
385
+ # Bar</p>
386
+ #
387
+ # And finally:
388
+ #
389
+ # %img
390
+ # %pre><
391
+ # foo
392
+ # bar
393
+ # %img
394
+ #
395
+ # is compiled to:
396
+ #
397
+ # <img /><pre>foo
398
+ # bar</pre><img />
399
+ #
317
400
  # ==== =
318
- #
401
+ #
319
402
  # <tt>=</tt> is placed at the end of a tag definition,
320
403
  # after class, id, and attribute declarations.
321
404
  # It's just a shortcut for inserting Ruby code into an element.
@@ -324,45 +407,63 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
324
407
  # However, if the result is short enough,
325
408
  # it is displayed entirely on one line.
326
409
  # For example:
327
- #
410
+ #
328
411
  # %p= "hello"
329
- #
412
+ #
330
413
  # is not quite the same as:
331
- #
414
+ #
332
415
  # %p
333
416
  # = "hello"
334
- #
417
+ #
335
418
  # It's compiled to:
336
- #
419
+ #
337
420
  # <p>hello</p>
338
- #
421
+ #
422
+ # ==== ~
423
+ #
424
+ # ~ works just like =, except that it runs Haml::Helpers#find_and_preserve on its input.
425
+ # For example,
426
+ #
427
+ # ~ "Foo\n<pre>Bar\nBaz</pre>"
428
+ #
429
+ # is the same as:
430
+ #
431
+ # = find_and_preserve("Foo\n<pre>Bar\nBaz</pre>")
432
+ #
433
+ # and is compiled to:
434
+ #
435
+ # Foo
436
+ # <pre>Bar&#x000A;Baz</pre>
437
+ #
438
+ # See also Whitespace Preservation, below.
439
+ #
339
440
  # === XHTML Helpers
340
- #
441
+ #
341
442
  # ==== No Special Character
342
- #
443
+ #
343
444
  # If no special character appears at the beginning of a line,
344
445
  # the line is rendered as plain text.
345
446
  # For example:
346
- #
447
+ #
347
448
  # %gee
348
449
  # %whiz
349
450
  # Wow this is cool!
350
- #
451
+ #
351
452
  # is compiled to:
352
- #
453
+ #
353
454
  # <gee>
354
455
  # <whiz>
355
456
  # Wow this is cool!
356
457
  # </whiz>
357
458
  # </gee>
358
- #
459
+ #
359
460
  # ==== !!!
360
- #
461
+ #
361
462
  # When describing XHTML documents with Haml,
362
463
  # you can have a document type or XML prolog generated automatically
363
464
  # by including the characters <tt>!!!</tt>.
364
465
  # For example:
365
- #
466
+ #
366
467
  # !!! XML
367
468
  # !!!
368
469
  # %html
@@ -371,9 +472,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
371
472
  # %body
372
473
  # %h1 I am the international space station
373
474
  # %p Sign my guestbook
374
- #
475
+ #
375
476
  # is compiled to:
376
- #
477
+ #
377
478
  # <?xml version="1.0" encoding="utf-8" ?>
378
479
  # <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
379
480
  # <html>
@@ -385,112 +486,112 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
385
486
  # <p>Sign my guestbook</p>
386
487
  # </body>
387
488
  # </html>
388
- #
489
+ #
389
490
  # You can also specify the version and type of XHTML after the <tt>!!!</tt>.
390
491
  # XHTML 1.0 Strict, Transitional, and Frameset and XHTML 1.1 are supported.
391
492
  # The default version is 1.0 and the default type is Transitional.
392
493
  # For example:
393
- #
494
+ #
394
495
  # !!! 1.1
395
- #
496
+ #
396
497
  # is compiled to:
397
- #
498
+ #
398
499
  # <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
399
- #
500
+ #
400
501
  # and
401
- #
502
+ #
402
503
  # !!! Strict
403
- #
504
+ #
404
505
  # is compiled to:
405
- #
506
+ #
406
507
  # <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
407
- #
508
+ #
408
509
  # If you're not using the UTF-8 character set for your document,
409
510
  # you can specify which encoding should appear
410
511
  # in the XML prolog in a similar way.
411
512
  # For example:
412
- #
513
+ #
413
514
  # !!! XML iso-8859-1
414
- #
515
+ #
415
516
  # is compiled to:
416
- #
517
+ #
417
518
  # <?xml version="1.0" encoding="iso-8859-1" ?>
418
- #
519
+ #
419
520
  # ==== /
420
- #
521
+ #
421
522
  # The forward slash character, when placed at the beginning of a line,
422
523
  # wraps all text after it in an HTML comment.
423
524
  # For example:
424
- #
525
+ #
425
526
  # %peanutbutterjelly
426
527
  # / This is the peanutbutterjelly element
427
528
  # I like sandwiches!
428
- #
529
+ #
429
530
  # is compiled to:
430
- #
531
+ #
431
532
  # <peanutbutterjelly>
432
533
  # <!-- This is the peanutbutterjelly element -->
433
534
  # I like sandwiches!
434
535
  # </peanutbutterjelly>
435
- #
536
+ #
436
537
  # The forward slash can also wrap indented sections of code. For example:
437
- #
538
+ #
438
539
  # /
439
540
  # %p This doesn't render...
440
541
  # %div
441
542
  # %h1 Because it's commented out!
442
- #
543
+ #
443
544
  # is compiled to:
444
- #
545
+ #
445
546
  # <!--
446
547
  # <p>This doesn't render...</p>
447
548
  # <div>
448
549
  # <h1>Because it's commented out!</h1>
449
550
  # </div>
450
551
  # -->
451
- #
552
+ #
452
553
  # You can also use Internet Explorer conditional comments
453
554
  # (about)[http://www.quirksmode.org/css/condcom.html]
454
555
  # by enclosing the condition in square brackets after the <tt>/</tt>.
455
556
  # For example:
456
- #
557
+ #
457
558
  # /[if IE]
458
559
  # %a{ :href => 'http://www.mozilla.com/en-US/firefox/' }
459
560
  # %h1 Get Firefox
460
- #
561
+ #
461
562
  # is compiled to:
462
- #
563
+ #
463
564
  # <!--[if IE]>
464
565
  # <a href='http://www.mozilla.com/en-US/firefox/'>
465
566
  # <h1>Get Firefox</h1>
466
567
  # </a>
467
568
  # <![endif]-->
468
- #
569
+ #
469
570
  # ==== \
470
- #
571
+ #
471
572
  # The backslash character escapes the first character of a line,
472
573
  # allowing use of otherwise interpreted characters as plain text.
473
574
  # For example:
474
- #
575
+ #
475
576
  # %title
476
577
  # = @title
477
578
  # \- MySite
478
- #
579
+ #
479
580
  # is compiled to:
480
- #
581
+ #
481
582
  # <title>
482
583
  # MyPage
483
584
  # - MySite
484
585
  # </title>
485
- #
586
+ #
486
587
  # ==== |
487
- #
588
+ #
488
589
  # The pipe character designates a multiline string.
489
590
  # It's placed at the end of a line
490
591
  # and means that all following lines that end with <tt>|</tt>
491
592
  # will be evaluated as though they were on the same line.
492
593
  # For example:
493
- #
594
+ #
494
595
  # %whoo
495
596
  # %hoo I think this might get |
496
597
  # pretty long so I should |
@@ -498,9 +599,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
498
599
  # multiline so it doesn't |
499
600
  # look awful. |
500
601
  # %p This is short.
501
- #
602
+ #
502
603
  # is compiled to:
503
- #
604
+ #
504
605
  # <whoo>
505
606
  # <hoo>
506
607
  # I think this might get pretty long so I should probably make it multiline so it doesn't look awful.
@@ -530,101 +631,180 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
530
631
  # <p>Hello, <em>World</em></p>
531
632
  # </p>
532
633
  #
634
+ # Filters can have Ruby code interpolated, like with ==.
635
+ # For example,
636
+ #
637
+ # - flavor = "raspberry"
638
+ # #content
639
+ # :textile
640
+ # I *really* prefer _#{h flavor}_ jam.
641
+ #
642
+ # is compiled to
643
+ #
644
+ # <div id='content'>
645
+ # <p>I <strong>really</strong> prefer <em>raspberry</em> jam.</p>
646
+ # </div>
647
+ #
533
648
  # Haml has the following filters defined:
534
649
  #
535
- # [plain] Does not parse the filtered text.
536
- # This is useful for large blocks of text without HTML tags,
537
- # when you don't want lines starting with <tt>.</tt> or <tt>-</tt>
538
- # to be parsed.
650
+ # [plain] Does not parse the filtered text.
651
+ # This is useful for large blocks of text without HTML tags,
652
+ # when you don't want lines starting with <tt>.</tt> or <tt>-</tt>
653
+ # to be parsed.
654
+ #
655
+ # [javascript] Surrounds the filtered text with <script> and CDATA tags.
656
+ # Useful for including inline Javascript.
539
657
  #
540
- # [ruby] Parses the filtered text with the normal Ruby interpreter.
541
- # All output sent to <tt>$stdout</tt>, like with +puts+,
542
- # is output into the Haml document.
543
- # Not available if the <tt>suppress_eval</tt> option is set to true.
658
+ # [escaped] Works the same as plain, but HTML-escapes the text
659
+ # before placing it in the document.
544
660
  #
545
- # [preserve] Inserts the filtered text into the template with whitespace preserved.
546
- # <tt>preserve</tt>d blocks of text aren't indented,
547
- # and newlines are replaced with the HTML escape code for newlines,
548
- # to preserve nice-looking output.
661
+ # [ruby] Parses the filtered text with the normal Ruby interpreter.
662
+ # All output sent to <tt>$stdout</tt>, like with +puts+,
663
+ # is output into the Haml document.
664
+ # Not available if the <tt>suppress_eval</tt> option is set to true.
665
+ # The Ruby code is evaluated in the same context as the Haml template.
549
666
  #
550
- # [erb] Parses the filtered text with ERB, like an RHTML template.
551
- # Not available if the <tt>suppress_eval</tt> option is set to true.
552
- # At the moment, this doesn't support access to variables
553
- # defined by Ruby on Rails or Haml code.
667
+ # [preserve] Inserts the filtered text into the template with whitespace preserved.
668
+ # <tt>preserve</tt>d blocks of text aren't indented,
669
+ # and newlines are replaced with the HTML escape code for newlines,
670
+ # to preserve nice-looking output.
671
+ # See also Whitespace Preservation, below.
554
672
  #
555
- # [sass] Parses the filtered text with Sass to produce CSS output.
673
+ # [erb] Parses the filtered text with ERB, like an RHTML template.
674
+ # Not available if the <tt>suppress_eval</tt> option is set to true.
675
+ # Embedded Ruby code is evaluated in the same context as the Haml template.
556
676
  #
557
- # [redcloth] Parses the filtered text with RedCloth (http://whytheluckystiff.net/ruby/redcloth),
558
- # which uses both Textile and Markdown syntax.
559
- # Only works if RedCloth is installed.
677
+ # [sass] Parses the filtered text with Sass to produce CSS output.
560
678
  #
561
- # [textile] Parses the filtered text with Textile (http://www.textism.com/tools/textile).
562
- # Only works if RedCloth is installed.
679
+ # [redcloth] Parses the filtered text with RedCloth (http://whytheluckystiff.net/ruby/redcloth),
680
+ # which uses both Textile and Markdown syntax.
681
+ # Only works if RedCloth is installed.
563
682
  #
564
- # [markdown] Parses the filtered text with Markdown (http://daringfireball.net/projects/markdown).
565
- # Only works if RedCloth or BlueCloth (http://www.deveiate.org/projects/BlueCloth)
566
- # is installed
567
- # (BlueCloth takes precedence if both are installed).
683
+ # [textile] Parses the filtered text with Textile (http://www.textism.com/tools/textile).
684
+ # Only works if RedCloth is installed.
685
+ #
686
+ # [markdown] Parses the filtered text with Markdown (http://daringfireball.net/projects/markdown).
687
+ # Only works if RedCloth or BlueCloth (http://www.deveiate.org/projects/BlueCloth)
688
+ # is installed
689
+ # (BlueCloth takes precedence if both are installed).
690
+ #
691
+ # You can also define your own filters (see Haml::Filters).
568
692
  #
569
- # You can also define your own filters (see Setting Options, below).
570
- #
571
693
  # === Ruby evaluators
572
- #
694
+ #
573
695
  # ==== =
574
- #
696
+ #
575
697
  # The equals character is followed by Ruby code,
576
698
  # which is evaluated and the output inserted into the document as plain text.
577
699
  # For example:
578
- #
700
+ #
579
701
  # %p
580
702
  # = ['hi', 'there', 'reader!'].join " "
581
703
  # = "yo"
582
- #
704
+ #
583
705
  # is compiled to:
584
- #
706
+ #
585
707
  # <p>
586
708
  # hi there reader!
587
709
  # yo
588
710
  # </p>
589
711
  #
590
- # You can also use two equal signs, <tt>==</tt>,
591
- # along with conventional Ruby string-embedding syntax
592
- # to easily embed Ruby code in otherwise static text.
593
- # For example:
712
+ # If the <tt>:escape_html</tt> option is set, <tt>=</tt> will sanitize any
713
+ # HTML-sensitive characters generated by the script. For example:
594
714
  #
595
- # %p
596
- # == 1 + 1 = #{1 + 1}
715
+ # = '<script>alert("I\'m evil!");</script>'
597
716
  #
598
- # is compiled to:
717
+ # would be compiled to
718
+ #
719
+ # &lt;script&gt;alert(&quot;I'm evil!&quot;);&lt;/script&gt;
599
720
  #
600
- # <p>
601
- # 1 + 1 = 2
602
- # </p>
603
- #
604
721
  # ==== -
605
- #
722
+ #
606
723
  # The hyphen character makes the text following it into "silent script":
607
724
  # Ruby script that is evaluated, but not output.
608
- #
725
+ #
609
726
  # <b>It is not recommended that you use this widely;
610
727
  # almost all processing code and logic should be restricted
611
728
  # to the Controller, the Helper, or partials.</b>
612
- #
729
+ #
613
730
  # For example:
614
- #
731
+ #
615
732
  # - foo = "hello"
616
733
  # - foo << " there"
617
734
  # - foo << " you!"
618
735
  # %p= foo
619
- #
736
+ #
620
737
  # is compiled to:
621
- #
738
+ #
622
739
  # <p>
623
740
  # hello there you!
624
741
  # </p>
625
- #
742
+ #
743
+ # ==== ==
744
+ #
745
+ # Two equals characters interpolates Ruby code into plain text,
746
+ # similarly to Ruby string interpolation.
747
+ # For example,
748
+ #
749
+ # %p== This is #{h quality} cake!
750
+ #
751
+ # is the same as
752
+ #
753
+ # %p= "This is #{h quality} cake!"
754
+ #
755
+ # and might compile to
756
+ #
757
+ # <p>This is scrumptious cake!</p>
758
+ #
759
+ # Backslashes can be used to escape "#{" strings,
760
+ # but they don't act as escapes anywhere else in the string.
761
+ # For example:
762
+ #
763
+ # %p
764
+ # == \\ Look at \\#{h word} lack of backslash: \#{foo}
765
+ #
766
+ # might compile to
767
+ #
768
+ # <p>
769
+ # \\ Look at \yon lack of backslash: #{foo}
770
+ # </p>
771
+ #
772
+ # ==== &=
773
+ #
774
+ # An ampersand followed by one or two equals characters
775
+ # evaluates Ruby code just like the equals without the ampersand,
776
+ # but sanitizes any HTML-sensitive characters in the result of the code.
777
+ # For example:
778
+ #
779
+ # &= "I like cheese & crackers"
780
+ #
781
+ # compiles to
782
+ #
783
+ # I like cheese &amp; crackers
784
+ #
785
+ # If the <tt>:escape_html</tt> option is set,
786
+ # &= behaves identically to =.
787
+ #
788
+ # ==== !=
789
+ #
790
+ # An exclamation mark followed by one or two equals characters
791
+ # evaluates Ruby code just like the equals would,
792
+ # but never sanitizes the HTML.
793
+ #
794
+ # By default, the single equals doesn't sanitize HTML either.
795
+ # However, if the <tt>:escape_html</tt> option is set, = will sanitize the HTML, but != still won't.
796
+ # For example, if <tt>:escape_html</tt> is set:
797
+ #
798
+ # = "I feel <strong>!"
799
+ # != "I feel <strong>!"
800
+ #
801
+ # compiles to
802
+ #
803
+ # I feel &lt;strong&gt;!
804
+ # I feel <strong>!
805
+ #
626
806
  # ===== Blocks
627
- #
807
+ #
628
808
  # Ruby blocks, like XHTML tags, don't need to be explicitly closed in Haml.
629
809
  # Rather, they're automatically closed, based on indentation.
630
810
  # A block begins whenever the indentation is increased
@@ -632,13 +812,13 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
632
812
  # It ends when the indentation decreases
633
813
  # (as long as it's not an +else+ clause or something similar).
634
814
  # For example:
635
- #
815
+ #
636
816
  # - (42...47).each do |i|
637
817
  # %p= i
638
818
  # %p See, I can count!
639
- #
819
+ #
640
820
  # is compiled to:
641
- #
821
+ #
642
822
  # <p>
643
823
  # 42
644
824
  # </p>
@@ -654,9 +834,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
654
834
  # <p>
655
835
  # 46
656
836
  # </p>
657
- #
837
+ #
658
838
  # Another example:
659
- #
839
+ #
660
840
  # %p
661
841
  # - case 2
662
842
  # - when 1
@@ -665,9 +845,9 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
665
845
  # = "2?"
666
846
  # - when 3
667
847
  # = "3."
668
- #
848
+ #
669
849
  # is compiled to:
670
- #
850
+ #
671
851
  # <p>
672
852
  # 2?
673
853
  # </p>
@@ -678,35 +858,52 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
678
858
  # signifies a silent comment.
679
859
  # Any text following this isn't rendered in the resulting document
680
860
  # at all.
681
- #
861
+ #
682
862
  # For example:
683
863
  #
684
- # %p foo
685
- # -# This is a comment
686
- # %p bar
864
+ # %p foo
865
+ # -# This is a comment
866
+ # %p bar
687
867
  #
688
868
  # is compiled to:
689
869
  #
690
- # <p>foo</p>
691
- # <p>bar</p>
870
+ # <p>foo</p>
871
+ # <p>bar</p>
692
872
  #
693
873
  # You can also nest text beneath a silent comment.
694
874
  # None of this text will be rendered.
695
875
  # For example:
696
876
  #
697
- # %p foo
698
- # -#
699
- # This won't be displayed
700
- # Nor will this
701
- # %p bar
877
+ # %p foo
878
+ # -#
879
+ # This won't be displayed
880
+ # Nor will this
881
+ # %p bar
702
882
  #
703
883
  # is compiled to:
704
884
  #
705
- # <p>foo</p>
706
- # <p>bar</p>
707
- #
885
+ # <p>foo</p>
886
+ # <p>bar</p>
887
+ #
708
888
  # == Other Useful Things
709
889
  #
890
+ # === Whitespace Preservation
891
+ #
892
+ # Sometimes you don't want Haml to indent all your text.
893
+ # For example, tags like +pre+ and +textarea+ are whitespace-sensitive;
894
+ # indenting the text makes them render wrong.
895
+ #
896
+ # Haml deals with this by "preserving" newlines before they're put into the document --
897
+ # converting them to the XHTML whitespace escape code, <tt>&#x000A;</tt>.
898
+ # Then Haml won't try to re-format the indentation.
899
+ #
900
+ # Literal +textarea+ and +pre+ tags automatically preserve their content.
901
+ # Dynamically can't be caught automatically,
902
+ # and so should be passed through Haml::Helpers#find_and_preserve or the <tt>~</tt> command,
903
+ # which has the same effect (see above).
904
+ #
905
+ # Blocks of literal text can be preserved using the :preserve filter (see above).
906
+ #
710
907
  # === Helpers
711
908
  #
712
909
  # Haml offers a bunch of helpers that are useful
@@ -714,19 +911,30 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
714
911
  # creating nicely indented output for user-defined helpers,
715
912
  # and other useful things.
716
913
  # The helpers are all documented in the Haml::Helpers and Haml::Helpers::ActionViewExtensions modules.
717
- #
914
+ #
718
915
  # === Haml Options
719
- #
916
+ #
720
917
  # Options can be set by setting the hash <tt>Haml::Template.options</tt>
721
918
  # from <tt>environment.rb</tt> in Rails,
722
919
  # or by passing an options hash to Haml::Engine.
723
920
  # Available options are:
724
- #
921
+ #
922
+ # [<tt>:output</tt>] Determines the output format. The default is :xhtml.
923
+ # Other options are :html4 and :html5, which are
924
+ # identical to :xhtml except there are no self-closing tags,
925
+ # XML prolog is ignored and correct DOCTYPEs are generated.
926
+ #
927
+ # [<tt>:escape_html</tt>] Sets whether or not to escape HTML-sensitive characters in script.
928
+ # If this is true, = behaves like &=;
929
+ # otherwise, it behaves like !=.
930
+ # <b>Note that this escapes tag attributes.</b>
931
+ # Defaults to false.
932
+ #
725
933
  # [<tt>:suppress_eval</tt>] Whether or not attribute hashes and Ruby scripts
726
934
  # designated by <tt>=</tt> or <tt>~</tt> should be
727
935
  # evaluated. If this is true, said scripts are
728
936
  # rendered as empty strings. Defaults to false.
729
- #
937
+ #
730
938
  # [<tt>:attr_wrapper</tt>] The character that should wrap element attributes.
731
939
  # This defaults to <tt>'</tt> (an apostrophe). Characters
732
940
  # of this type within the attributes will be escaped
@@ -739,20 +947,75 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
739
947
  # so it's really only useful for the user to assign
740
948
  # when dealing with Haml programatically.
741
949
  #
742
- # [<tt>:filters</tt>] A hash of filters that can be applied to Haml code.
743
- # The keys are the string names of the filters;
744
- # the values are references to the classes of the filters.
745
- # User-defined filters should always have lowercase keys,
746
- # and should have:
747
- # * An +initialize+ method that accepts one parameter,
748
- # the text to be filtered.
749
- # * A +render+ method that returns the result of the filtering.
950
+ # [<tt>:line</tt>] The line offset of the Haml template being parsed.
951
+ # This is useful for inline templates,
952
+ # similar to the last argument to Kernel#eval.
750
953
  #
751
954
  # [<tt>:autoclose</tt>] A list of tag names that should be automatically self-closed
752
955
  # if they have no content.
753
- # Defaults to <tt>['meta', 'img', 'link', 'br', 'hr', 'input', 'area']</tt>.
956
+ # Defaults to <tt>['meta', 'img', 'link', 'br', 'hr', 'input', 'area', 'param', 'col', 'base']</tt>.
957
+ #
958
+ # [<tt>:preserve</tt>] A list of tag names that should automatically have their newlines preserved
959
+ # using the Haml::Helpers#preserve helper.
960
+ # This means that any content given on the same line as the tag will be preserved.
961
+ # For example:
962
+ #
963
+ # %textarea= "Foo\nBar"
964
+ #
965
+ # compiles to:
966
+ #
967
+ # <textarea>Foo&&#x000A;Bar</textarea>
968
+ #
969
+ # Defaults to <tt>['textarea', 'pre']</tt>.
970
+ #
971
+ # See also Whitespace Preservation, above.
754
972
  #
755
973
  module Haml
974
+ # Returns a hash representing the version of Haml.
975
+ # The :major, :minor, and :teeny keys have their respective numbers.
976
+ # The :string key contains a human-readable string representation of the version.
977
+ # If Haml is checked out from Git,
978
+ # the :rev key will have the revision hash.
979
+ def self.version
980
+ return @@version if defined?(@@version)
981
+
982
+ numbers = File.read(scope('VERSION')).strip.split('.').map { |n| n.to_i }
983
+ @@version = {
984
+ :major => numbers[0],
985
+ :minor => numbers[1],
986
+ :teeny => numbers[2]
987
+ }
988
+ @@version[:string] = [:major, :minor, :teeny].map { |comp| @@version[comp] }.compact.join('.')
989
+
990
+ if File.exists?(scope('REVISION'))
991
+ rev = File.read(scope('REVISION')).strip
992
+ rev = nil if rev !~ /[a-f0-9]+/
993
+ end
994
+
995
+ if rev.nil? && File.exists?(scope('.git/HEAD'))
996
+ rev = File.read(scope('.git/HEAD')).strip
997
+ if rev =~ /^ref: (.*)$/
998
+ rev = File.read(scope(".git/#{$1}")).strip
999
+ end
1000
+ end
1001
+
1002
+ if rev
1003
+ @@version[:rev] = rev
1004
+ @@version[:string] << "." << rev[0...7]
1005
+ end
1006
+
1007
+ @@version
1008
+ end
1009
+
1010
+ # Returns the path of file relative to the Haml root.
1011
+ def self.scope(file) # :nodoc:
1012
+ File.join(File.dirname(__FILE__), '..', file)
1013
+ end
1014
+
1015
+ # A string representing the version of Haml.
1016
+ # A more fine-grained representation is generated by Haml.version.
1017
+ VERSION = version[:string] unless defined?(Haml::VERSION)
1018
+
756
1019
  # This method is called by init.rb,
757
1020
  # which is run by Rails on startup.
758
1021
  # We use it rather than putting stuff straight into init.rb