12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- module Sass
- # This module contains functionality that's shared between Haml and Sass.
- module Shared
- extend self
- # Scans through a string looking for the interoplation-opening `#{`
- # and, when it's found, yields the scanner to the calling code
- # so it can handle it properly.
- #
- # The scanner will have any backslashes immediately in front of the `#{`
- # as the second capture group (`scan[2]`),
- # and the text prior to that as the first (`scan[1]`).
- #
- # @yieldparam scan [StringScanner] The scanner scanning through the string
- # @return [String] The text remaining in the scanner after all `#{`s have been processed
- def handle_interpolation(str)
- scan = Sass::Util::MultibyteStringScanner.new(str)
- yield scan while scan.scan(/(.*?)(\\*)\#\{/m)
- scan.rest
- end
- # Moves a scanner through a balanced pair of characters.
- # For example:
- #
- # Foo (Bar (Baz bang) bop) (Bang (bop bip))
- # ^ ^
- # from to
- #
- # @param scanner [StringScanner] The string scanner to move
- # @param start [Character] The character opening the balanced pair.
- # A `Fixnum` in 1.8, a `String` in 1.9
- # @param finish [Character] The character closing the balanced pair.
- # A `Fixnum` in 1.8, a `String` in 1.9
- # @param count [Fixnum] The number of opening characters matched
- # before calling this method
- # @return [(String, String)] The string matched within the balanced pair
- # and the rest of the string.
- # `["Foo (Bar (Baz bang) bop)", " (Bang (bop bip))"]` in the example above.
- def balance(scanner, start, finish, count = 0)
- str = ''
- scanner = Sass::Util::MultibyteStringScanner.new(scanner) unless scanner.is_a? StringScanner
- regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]", Regexp::MULTILINE)
- while scanner.scan(regexp)
- str << scanner.matched
- count += 1 if scanner.matched[-1] == start
- count -= 1 if scanner.matched[-1] == finish
- return [str.strip, scanner.rest] if count == 0
- end
- end
- # Formats a string for use in error messages about indentation.
- #
- # @param indentation [String] The string used for indentation
- # @param was [Boolean] Whether or not to add `"was"` or `"were"`
- # (depending on how many characters were in `indentation`)
- # @return [String] The name of the indentation (e.g. `"12 spaces"`, `"1 tab"`)
- def human_indentation(indentation, was = false)
- if !indentation.include?(?\t)
- noun = 'space'
- elsif !indentation.include?(?\s)
- noun = 'tab'
- else
- return indentation.inspect + (was ? ' was' : '')
- end
- singular = indentation.length == 1
- if was
- was = singular ? ' was' : ' were'
- else
- was = ''
- end
- "#{indentation.length} #{noun}#{'s' unless singular}#{was}"
- end
- end
- end
|