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.
- data/FAQ +138 -0
- data/MIT-LICENSE +1 -1
- data/{README → README.rdoc} +66 -3
- data/Rakefile +111 -147
- data/VERSION +1 -1
- data/bin/css2sass +0 -0
- data/bin/haml +0 -0
- data/bin/html2haml +0 -0
- data/bin/sass +0 -0
- data/init.rb +6 -1
- data/lib/haml.rb +464 -201
- data/lib/haml/buffer.rb +117 -63
- data/lib/haml/engine.rb +63 -44
- data/lib/haml/error.rb +16 -6
- data/lib/haml/exec.rb +37 -7
- data/lib/haml/filters.rb +213 -68
- data/lib/haml/helpers.rb +95 -60
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/helpers/action_view_mods.rb +54 -6
- data/lib/haml/html.rb +6 -6
- data/lib/haml/precompiler.rb +254 -133
- data/lib/haml/template.rb +3 -6
- data/lib/haml/template/patch.rb +9 -2
- data/lib/haml/template/plugin.rb +52 -23
- data/lib/sass.rb +157 -12
- data/lib/sass/constant.rb +22 -22
- data/lib/sass/constant/color.rb +13 -13
- data/lib/sass/constant/literal.rb +7 -7
- data/lib/sass/constant/number.rb +9 -9
- data/lib/sass/constant/operation.rb +4 -4
- data/lib/sass/constant/string.rb +3 -3
- data/lib/sass/css.rb +104 -31
- data/lib/sass/engine.rb +120 -39
- data/lib/sass/error.rb +1 -1
- data/lib/sass/plugin.rb +14 -3
- data/lib/sass/plugin/merb.rb +6 -2
- data/lib/sass/tree/attr_node.rb +5 -5
- data/lib/sass/tree/directive_node.rb +2 -7
- data/lib/sass/tree/node.rb +1 -12
- data/lib/sass/tree/rule_node.rb +39 -31
- data/lib/sass/tree/value_node.rb +1 -1
- data/test/benchmark.rb +67 -80
- data/test/haml/engine_test.rb +284 -84
- data/test/haml/helper_test.rb +51 -15
- data/test/haml/results/content_for_layout.xhtml +1 -2
- data/test/haml/results/eval_suppressed.xhtml +2 -4
- data/test/haml/results/filters.xhtml +44 -15
- data/test/haml/results/helpers.xhtml +2 -3
- data/test/haml/results/just_stuff.xhtml +2 -6
- data/test/haml/results/nuke_inner_whitespace.xhtml +34 -0
- data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/test/haml/results/original_engine.xhtml +3 -7
- data/test/haml/results/partials.xhtml +1 -0
- data/test/haml/results/tag_parsing.xhtml +1 -6
- data/test/haml/results/very_basic.xhtml +2 -4
- data/test/haml/results/whitespace_handling.xhtml +13 -21
- data/test/haml/template_test.rb +8 -15
- data/test/haml/templates/_partial.haml +1 -0
- data/test/haml/templates/filters.haml +48 -7
- data/test/haml/templates/just_stuff.haml +1 -2
- data/test/haml/templates/nuke_inner_whitespace.haml +26 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/tag_parsing.haml +0 -3
- data/test/haml/test_helper.rb +15 -0
- data/test/sass/engine_test.rb +80 -34
- data/test/sass/plugin_test.rb +1 -1
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/templates/import.sass +4 -1
- data/test/sass/templates/importee.sass +4 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- metadata +65 -51
- data/lib/haml/util.rb +0 -18
- data/test/haml/runner.rb +0 -16
- data/test/profile.rb +0 -65
data/lib/haml/template.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
require 'haml/engine'
|
2
|
-
require 'rubygems'
|
3
|
-
require 'active_support'
|
4
|
-
require 'action_view'
|
5
2
|
|
6
3
|
module Haml
|
7
4
|
class Template
|
8
5
|
class << self
|
9
6
|
@@options = {}
|
10
7
|
|
11
|
-
# Gets various options for Haml. See README for details.
|
8
|
+
# Gets various options for Haml. See README.rdoc for details.
|
12
9
|
def options
|
13
10
|
@@options
|
14
11
|
end
|
15
12
|
|
16
|
-
# Sets various options for Haml. See README for details.
|
13
|
+
# Sets various options for Haml. See README.rdoc for details.
|
17
14
|
def options=(value)
|
18
15
|
@@options = value
|
19
16
|
end
|
@@ -38,7 +35,7 @@ if defined?(RAILS_ROOT)
|
|
38
35
|
# because the new init file is sufficiently flexible
|
39
36
|
# to not need updating.
|
40
37
|
rails_init_file = File.join(RAILS_ROOT, 'vendor', 'plugins', 'haml', 'init.rb')
|
41
|
-
haml_init_file =
|
38
|
+
haml_init_file = Haml.scope('init.rb')
|
42
39
|
if File.exists?(rails_init_file)
|
43
40
|
require 'fileutils'
|
44
41
|
FileUtils.cp(haml_init_file, rails_init_file) unless FileUtils.cmp(rails_init_file, haml_init_file)
|
data/lib/haml/template/patch.rb
CHANGED
@@ -26,7 +26,7 @@ module ActionView
|
|
26
26
|
def compile_haml(template, file_name, local_assigns)
|
27
27
|
render_symbol = assign_method_name(:haml, template, file_name)
|
28
28
|
locals = local_assigns.keys
|
29
|
-
|
29
|
+
|
30
30
|
@@template_args[render_symbol] ||= {}
|
31
31
|
locals_keys = @@template_args[render_symbol].keys | locals
|
32
32
|
@@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h }
|
@@ -42,7 +42,14 @@ module ActionView
|
|
42
42
|
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
base_path = if defined?(extract_base_path_from)
|
46
|
+
# Rails 2.0.x
|
47
|
+
extract_base_path_from(file_name) || view_paths.first
|
48
|
+
else
|
49
|
+
# Rails <=1.2.6
|
50
|
+
@base_path
|
51
|
+
end
|
52
|
+
raise ActionView::TemplateError.new(base_path, file_name || template, @assigns, template, e)
|
46
53
|
end
|
47
54
|
|
48
55
|
@@compile_time[render_symbol] = Time.now
|
data/lib/haml/template/plugin.rb
CHANGED
@@ -3,41 +3,70 @@
|
|
3
3
|
# using the > 2.0.1 template handler API.
|
4
4
|
|
5
5
|
module Haml
|
6
|
-
class
|
6
|
+
class Plugin < ActionView::TemplateHandler
|
7
7
|
include ActionView::TemplateHandlers::Compilable if defined?(ActionView::TemplateHandlers::Compilable)
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
end
|
9
|
+
def compile(template)
|
10
|
+
options = Haml::Template.options.dup
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
# template is a template object in Rails >=2.1.0,
|
13
|
+
# a source string previously
|
14
|
+
if template.respond_to? :source
|
15
|
+
options[:filename] = template.filename
|
16
|
+
source = template.source
|
17
|
+
else
|
18
|
+
source = template
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
@view = view
|
21
|
+
Haml::Engine.new(source, options).send(:precompiled_with_ambles, [])
|
23
22
|
end
|
24
23
|
|
25
|
-
def compile(template)
|
26
|
-
options = Haml::Template.options.dup
|
27
|
-
Haml::Engine.new(template, options).send(:precompiled_with_ambles, [])
|
28
|
-
end
|
29
|
-
|
30
24
|
def cache_fragment(block, name = {}, options = nil)
|
31
25
|
@view.fragment_for(block, name, options) do
|
32
26
|
eval("_hamlout.buffer", block.binding)
|
33
27
|
end
|
34
28
|
end
|
35
|
-
|
36
|
-
def read_template_file(template_path, extension)
|
37
|
-
File.read(template_path)
|
38
|
-
end
|
39
29
|
end
|
40
30
|
end
|
41
31
|
|
42
|
-
ActionView::
|
32
|
+
if defined? ActionView::Template and ActionView::Template.respond_to? :register_template_handler
|
33
|
+
ActionView::Template
|
34
|
+
else
|
35
|
+
ActionView::Base
|
36
|
+
end.register_template_handler(:haml, Haml::Plugin)
|
37
|
+
|
38
|
+
# In Rails 2.0.2, ActionView::TemplateError took arguments
|
39
|
+
# that we can't fill in from the Haml::Plugin context.
|
40
|
+
# Thus, we've got to monkeypatch ActionView::Base to catch the error.
|
41
|
+
if ActionView::TemplateError.instance_method(:initialize).arity == 5
|
42
|
+
class ActionView::Base
|
43
|
+
def compile_template(handler, template, file_name, local_assigns)
|
44
|
+
render_symbol = assign_method_name(handler, template, file_name)
|
45
|
+
|
46
|
+
# Move begin up two lines so it captures compilation exceptions.
|
47
|
+
begin
|
48
|
+
render_source = create_template_source(handler, template, render_symbol, local_assigns.keys)
|
49
|
+
line_offset = @@template_args[render_symbol].size + handler.line_offset
|
50
|
+
|
51
|
+
file_name = 'compiled-template' if file_name.blank?
|
52
|
+
CompiledTemplates.module_eval(render_source, file_name, -line_offset)
|
53
|
+
rescue Exception => e # errors from template code
|
54
|
+
if logger
|
55
|
+
logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
|
56
|
+
logger.debug "Function body: #{render_source}"
|
57
|
+
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# There's no way to tell Haml about the filename,
|
61
|
+
# so we've got to insert it ourselves.
|
62
|
+
e.backtrace[0].gsub!('(haml)', file_name) if e.is_a?(Haml::Error)
|
63
|
+
|
64
|
+
raise ActionView::TemplateError.new(extract_base_path_from(file_name) || view_paths.first, file_name || template, @assigns, template, e)
|
65
|
+
end
|
66
|
+
|
67
|
+
@@compile_time[render_symbol] = Time.now
|
68
|
+
# logger.debug "Compiled template #{file_name || template}\n ==> #{render_symbol}" if logger
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
43
72
|
# :startdoc:
|
data/lib/sass.rb
CHANGED
@@ -11,7 +11,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
11
11
|
# and implements various features that are useful
|
12
12
|
# for creating manageable stylesheets.
|
13
13
|
#
|
14
|
-
# == Features
|
14
|
+
# == Features
|
15
15
|
#
|
16
16
|
# * Whitespace active
|
17
17
|
# * Well-formatted output
|
@@ -32,13 +32,13 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
32
32
|
#
|
33
33
|
# To enable it as a Rails plugin,
|
34
34
|
# then run
|
35
|
-
#
|
35
|
+
#
|
36
36
|
# haml --rails path/to/rails/app
|
37
|
-
#
|
37
|
+
#
|
38
38
|
# To enable Sass in Merb,
|
39
39
|
# add
|
40
40
|
#
|
41
|
-
# dependency "haml"
|
41
|
+
# dependency "merb-haml"
|
42
42
|
#
|
43
43
|
# to config/dependencies.rb.
|
44
44
|
#
|
@@ -128,7 +128,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
128
128
|
#
|
129
129
|
# By default, either attribute syntax may be used.
|
130
130
|
# If you want to force one or the other,
|
131
|
-
# see the
|
131
|
+
# see the <tt>:attribute_syntax</tt> option below.
|
132
132
|
#
|
133
133
|
# === Nested Rules
|
134
134
|
#
|
@@ -157,12 +157,12 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
157
157
|
#
|
158
158
|
# #main
|
159
159
|
# :width 97%
|
160
|
-
#
|
160
|
+
#
|
161
161
|
# p, div
|
162
162
|
# :font-size 2em
|
163
163
|
# a
|
164
164
|
# :font-weight bold
|
165
|
-
#
|
165
|
+
#
|
166
166
|
# pre
|
167
167
|
# :font-size 3em
|
168
168
|
#
|
@@ -363,6 +363,39 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
363
363
|
# #main {
|
364
364
|
# content: string(Hello, "Hubert" Bean.) }
|
365
365
|
#
|
366
|
+
# === Optional Assignment
|
367
|
+
#
|
368
|
+
# You can assign Sass constants if they aren't already assigned
|
369
|
+
# using the ||= assignment operator.
|
370
|
+
# This means that if the constant has already been assigned to,
|
371
|
+
# it won't be re-assigned,
|
372
|
+
# but if it doesn't have a value yet,
|
373
|
+
# it will be given one.
|
374
|
+
# For example:
|
375
|
+
#
|
376
|
+
# !content = "First content"
|
377
|
+
# !content ||= "Second content?"
|
378
|
+
#
|
379
|
+
# #main
|
380
|
+
# content = content
|
381
|
+
#
|
382
|
+
# is compiled to:
|
383
|
+
#
|
384
|
+
# #main {
|
385
|
+
# content: First content; }
|
386
|
+
#
|
387
|
+
# However,
|
388
|
+
#
|
389
|
+
# !content ||= "Second content?"
|
390
|
+
#
|
391
|
+
# #main
|
392
|
+
# content = content
|
393
|
+
#
|
394
|
+
# is compiled to:
|
395
|
+
#
|
396
|
+
# #main {
|
397
|
+
# content: Second content?; }
|
398
|
+
#
|
366
399
|
# === Default Concatenation
|
367
400
|
#
|
368
401
|
# All those plusses and quotes for concatenating strings
|
@@ -453,6 +486,40 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
453
486
|
# might compile to either,
|
454
487
|
# depending on whether a file called "foo.sass" existed.
|
455
488
|
#
|
489
|
+
# === @font-face, @media, etc.
|
490
|
+
#
|
491
|
+
# Sass behaves as you'd expect for normal CSS @-directives.
|
492
|
+
# For example:
|
493
|
+
#
|
494
|
+
# @font-face
|
495
|
+
# font-family: "Bitstream Vera Sans"
|
496
|
+
# src: url(http://foo.bar/bvs")
|
497
|
+
#
|
498
|
+
# compiles to:
|
499
|
+
#
|
500
|
+
# @font-face {
|
501
|
+
# font-family: "Bitstream Vera Sans";
|
502
|
+
# src: url(http://foo.bar/bvs"); }
|
503
|
+
#
|
504
|
+
# and
|
505
|
+
#
|
506
|
+
# @media print
|
507
|
+
# #sidebar
|
508
|
+
# display: none
|
509
|
+
#
|
510
|
+
# #main
|
511
|
+
# background-color: white
|
512
|
+
#
|
513
|
+
# compiles to:
|
514
|
+
#
|
515
|
+
# @media print {
|
516
|
+
# #sidebar {
|
517
|
+
# display: none; }
|
518
|
+
#
|
519
|
+
# #main {
|
520
|
+
# background-color: white; }
|
521
|
+
# }
|
522
|
+
#
|
456
523
|
# == Comments
|
457
524
|
#
|
458
525
|
# === Silent Comments
|
@@ -528,6 +595,84 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
528
595
|
# background-image: url(/images/pbj.png);
|
529
596
|
# color: red; }
|
530
597
|
#
|
598
|
+
# == Mixins
|
599
|
+
#
|
600
|
+
# Mixins enable you to define groups of CSS attributes and
|
601
|
+
# then include them inline in any number of selectors
|
602
|
+
# throughout the document.
|
603
|
+
#
|
604
|
+
# === Defining a Mixin
|
605
|
+
#
|
606
|
+
# To define a mixin you use a slightly modified form of selector syntax.
|
607
|
+
# For example the 'large-text' mixin is defined as follows:
|
608
|
+
#
|
609
|
+
# =large-text
|
610
|
+
# :font
|
611
|
+
# :family Arial
|
612
|
+
# :size 20px
|
613
|
+
# :weight bold
|
614
|
+
# :color #ff0000
|
615
|
+
#
|
616
|
+
# The initial '=' marks this as a mixin rather than a standard selector.
|
617
|
+
# The CSS rules that follow won't be included until the mixin is referenced later on.
|
618
|
+
# Anything you can put into a standard selector,
|
619
|
+
# you can put into a mixin definition. e.g.
|
620
|
+
#
|
621
|
+
# =clearfix
|
622
|
+
# display: inline-block
|
623
|
+
# &:after
|
624
|
+
# content: "."
|
625
|
+
# display: block
|
626
|
+
# height: 0
|
627
|
+
# clear: both
|
628
|
+
# visibility: hidden
|
629
|
+
# * html &
|
630
|
+
# height: 1px
|
631
|
+
#
|
632
|
+
#
|
633
|
+
# === Mixing it in
|
634
|
+
#
|
635
|
+
# Inlining a defined mixin is simple,
|
636
|
+
# just prepend a '+' symbol to the name of a mixin defined earlier in the document.
|
637
|
+
# So to inline the 'large-text' defined earlier,
|
638
|
+
# we include the statment '+large-text' in our selector definition thus:
|
639
|
+
#
|
640
|
+
# .page-title
|
641
|
+
# +large-text
|
642
|
+
# :padding 4px
|
643
|
+
# :margin
|
644
|
+
# :top 10px
|
645
|
+
#
|
646
|
+
#
|
647
|
+
# This will produce the following CSS output:
|
648
|
+
#
|
649
|
+
# .page-title {
|
650
|
+
# font-family: Arial;
|
651
|
+
# font-size: 20px;
|
652
|
+
# font-weight: bold;
|
653
|
+
# color: #ff0000;
|
654
|
+
# padding: 4px;
|
655
|
+
# margin-top: 10px;
|
656
|
+
# }
|
657
|
+
#
|
658
|
+
# Any number of mixins may be defined and there is no limit on
|
659
|
+
# the number that can be included in a particular selector.
|
660
|
+
#
|
661
|
+
# Mixin definitions can also include references to other mixins defined earlier in the file.
|
662
|
+
# E.g.
|
663
|
+
#
|
664
|
+
# =highlighted-background
|
665
|
+
# background:
|
666
|
+
# color: #fc0
|
667
|
+
# =header-text
|
668
|
+
# font:
|
669
|
+
# size: 20px
|
670
|
+
#
|
671
|
+
# =compound
|
672
|
+
# +highlighted-background
|
673
|
+
# +header-text
|
674
|
+
#
|
675
|
+
#
|
531
676
|
# == Output Style
|
532
677
|
#
|
533
678
|
# Although the default CSS style that Sass outputs is very nice,
|
@@ -601,7 +746,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
601
746
|
# #main { color: #fff; background-color: #000; }
|
602
747
|
# #main p { width: 10em; }
|
603
748
|
#
|
604
|
-
# .huge { font-size: 10em; font-weight: bold; text-decoration: underline; }
|
749
|
+
# .huge { font-size: 10em; font-weight: bold; text-decoration: underline; }
|
605
750
|
#
|
606
751
|
# === <tt>:compressed</tt>
|
607
752
|
#
|
@@ -611,7 +756,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
611
756
|
# It's not meant to be human-readable.
|
612
757
|
# For example:
|
613
758
|
#
|
614
|
-
# #main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
|
759
|
+
# #main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
|
615
760
|
#
|
616
761
|
# == Sass Options
|
617
762
|
#
|
@@ -634,7 +779,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
634
779
|
# For example: <tt>color: #0f3</tt>
|
635
780
|
# or <tt>width = !main_width</tt>.
|
636
781
|
# By default, either syntax is valid.
|
637
|
-
#
|
782
|
+
#
|
638
783
|
# [<tt>:never_update</tt>] Whether the CSS files should never be updated,
|
639
784
|
# even if the template file changes.
|
640
785
|
# Setting this to true may give small performance gains.
|
@@ -646,7 +791,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
646
791
|
# as opposed to only when the template has been modified.
|
647
792
|
# Defaults to false.
|
648
793
|
# Only has meaning within Ruby on Rails or Merb.
|
649
|
-
#
|
794
|
+
#
|
650
795
|
# [<tt>:always_check</tt>] Whether a Sass template should be checked for updates every
|
651
796
|
# time a controller is accessed,
|
652
797
|
# as opposed to only when the Rails server starts.
|
@@ -681,7 +826,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
681
826
|
# for Sass templates imported with the "@import" directive.
|
682
827
|
# This defaults to the working directory and, in Rails or Merb,
|
683
828
|
# whatever <tt>:template_location</tt> is.
|
684
|
-
#
|
829
|
+
#
|
685
830
|
module Sass; end
|
686
831
|
|
687
832
|
require 'sass/engine'
|
data/lib/sass/constant.rb
CHANGED
@@ -8,13 +8,13 @@ module Sass
|
|
8
8
|
|
9
9
|
# Whitespace characters
|
10
10
|
WHITESPACE = [?\ , ?\t, ?\n, ?\r]
|
11
|
-
|
11
|
+
|
12
12
|
# The character used to escape values
|
13
13
|
ESCAPE_CHAR = ?\\
|
14
14
|
|
15
15
|
# The character used to open and close strings
|
16
16
|
STRING_CHAR = ?"
|
17
|
-
|
17
|
+
|
18
18
|
# A mapping of syntactically-significant characters
|
19
19
|
# to parsed symbols
|
20
20
|
SYMBOLS = {
|
@@ -31,14 +31,14 @@ module Sass
|
|
31
31
|
}
|
32
32
|
|
33
33
|
# The regular expression used to parse constants
|
34
|
-
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+)\s
|
35
|
-
|
34
|
+
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+)\s*((?:\|\|)?=)\s*(.+)/
|
35
|
+
|
36
36
|
# First-order operations
|
37
37
|
FIRST_ORDER = [:times, :div, :mod]
|
38
|
-
|
38
|
+
|
39
39
|
# Second-order operations
|
40
40
|
SECOND_ORDER = [:plus, :minus]
|
41
|
-
|
41
|
+
|
42
42
|
class << self
|
43
43
|
def parse(value, constants, line)
|
44
44
|
begin
|
@@ -46,28 +46,28 @@ module Sass
|
|
46
46
|
rescue Sass::SyntaxError => e
|
47
47
|
if e.message == "Constant arithmetic error"
|
48
48
|
e.instance_eval do
|
49
|
-
@message += ": #{value.dump}"
|
49
|
+
@message += ": #{value.dump}."
|
50
50
|
end
|
51
51
|
end
|
52
52
|
e.sass_line = line
|
53
53
|
raise e
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
private
|
58
|
-
|
58
|
+
|
59
59
|
def tokenize(value)
|
60
60
|
escaped = false
|
61
61
|
is_string = false
|
62
62
|
beginning_of_token = true
|
63
63
|
str = ''
|
64
64
|
to_return = []
|
65
|
-
|
65
|
+
|
66
66
|
reset_str = Proc.new do
|
67
67
|
to_return << str unless str.empty?
|
68
68
|
''
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
value.each_byte do |byte|
|
72
72
|
unless escaped
|
73
73
|
if byte == ESCAPE_CHAR
|
@@ -97,7 +97,7 @@ module Sass
|
|
97
97
|
str = reset_str.call
|
98
98
|
next
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
symbol = SYMBOLS[byte]
|
102
102
|
|
103
103
|
# Adjacent values without an operator should be concatenated
|
@@ -135,28 +135,28 @@ module Sass
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
escaped = false
|
140
140
|
beginning_of_token = false
|
141
141
|
str << byte.chr
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
if is_string
|
145
|
-
raise Sass::SyntaxError.new("Unterminated string: #{value.dump}")
|
145
|
+
raise Sass::SyntaxError.new("Unterminated string: #{value.dump}.")
|
146
146
|
end
|
147
147
|
str = reset_str.call
|
148
148
|
to_return
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
def parenthesize(value)
|
152
152
|
parenthesize_helper(0, value, value.length)[0]
|
153
153
|
end
|
154
|
-
|
154
|
+
|
155
155
|
def parenthesize_helper(i, value, value_len, return_after_expr = false)
|
156
156
|
to_return = []
|
157
157
|
beginning = i
|
158
158
|
token = value[i]
|
159
|
-
|
159
|
+
|
160
160
|
while i < value_len && token != :close
|
161
161
|
if token == :open
|
162
162
|
to_return.push(*value[beginning...i])
|
@@ -194,13 +194,13 @@ module Sass
|
|
194
194
|
else
|
195
195
|
i += 1
|
196
196
|
end
|
197
|
-
|
197
|
+
|
198
198
|
token = value[i]
|
199
199
|
end
|
200
200
|
to_return.push(*value[beginning...i])
|
201
201
|
return to_return, i + 1
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
#--
|
205
205
|
# TODO: Don't pass around original value;
|
206
206
|
# have Constant.parse automatically add it to exception.
|
@@ -234,10 +234,10 @@ module Sass
|
|
234
234
|
end
|
235
235
|
end
|
236
236
|
end
|
237
|
-
|
237
|
+
|
238
238
|
def get_constant(value, constants)
|
239
239
|
to_return = constants[value]
|
240
|
-
raise SyntaxError.new("Undefined constant: \"!#{value}\"") unless to_return
|
240
|
+
raise SyntaxError.new("Undefined constant: \"!#{value}\".") unless to_return
|
241
241
|
to_return
|
242
242
|
end
|
243
243
|
end
|