module Haml::Util
def self.escape_html(html)
def self.escape_html(html) CGI.escapeHTML(html.to_s) end
def self.escape_html_safe(html)
def self.escape_html_safe(html) html = html.to_s (html.respond_to?(:html_safe?) && html.html_safe?) ? html : escape_html(html) end
def balance(scanner, start, finish, count = 0)
-
((String, String))
- The string matched within the balanced pair
Parameters:
-
count
(Fixnum
) -- The number of opening characters matched -
finish
(String
) -- The character closing the balanced pair. -
start
(String
) -- The character opening the balanced pair. -
scanner
(StringScanner
) -- The string scanner to move
def balance(scanner, start, finish, count = 0) str = ''.dup scanner = StringScanner.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
def check_encoding(str)
-
(String)
- `str`, potentially with encoding gotchas like BOMs removed
Other tags:
- Yieldparam: msg - The error message to be raised
Other tags:
- Yield: - A block in which an encoding error can be raised.
Parameters:
-
str
(String
) -- The string of which to check the encoding
def check_encoding(str) if str.valid_encoding? # Get rid of the Unicode BOM if possible # Shortcut for UTF-8 which might be the majority case if str.encoding == Encoding::UTF_8 return str.gsub(/\A\uFEFF/, '') elsif str.encoding.name =~ /^UTF-(16|32)(BE|LE)?$/ return str.gsub(Regexp.new("\\A\uFEFF".encode(str.encoding)), '') else return str end end encoding = str.encoding newlines = Regexp.new("\r\n|\r|\n".encode(encoding).force_encoding(Encoding::ASCII_8BIT)) str.force_encoding(Encoding::ASCII_8BIT).split(newlines).each_with_index do |line, i| begin line.encode(encoding) rescue Encoding::UndefinedConversionError => e yield <<MSG.rstrip, i + 1 lid #{encoding.name} character #{e.error_char.dump} end end return str end
def check_haml_encoding(str, &block)
-
(ArgumentError)
- if the document declares an unknown encoding
Returns:
-
(String)
- The original string encoded properly
Other tags:
- Yieldparam: msg - The error message to be raised
Other tags:
- Yield: - A block in which an encoding error can be raised.
Parameters:
-
str
(String
) -- The Haml template of which to check the encoding
def check_haml_encoding(str, &block) str = str.dup if str.frozen? bom, encoding = parse_haml_magic_comment(str) if encoding; str.force_encoding(encoding) elsif bom; str.force_encoding(Encoding::UTF_8) end return check_encoding(str, &block) end
def contains_interpolation?(str)
def contains_interpolation?(str) /#[\{$@]/ === str end
def handle_interpolation(str)
-
(String)
- The text remaining in the scanner after all `#{`s have been processed
Other tags:
- Yieldparam: scan - The scanner scanning through the string
def handle_interpolation(str) scan = StringScanner.new(str) yield scan while scan.scan(/(.*?)(\\*)#([\{@$])/) scan.rest end
def human_indentation(indentation)
-
(String)
- The name of the indentation (e.g. `"12 spaces"`, `"1 tab"`)
Parameters:
-
indentation
(String
) -- The string used for indentation
def human_indentation(indentation) if !indentation.include?(?\t) noun = 'space' elsif !indentation.include?(?\s) noun = 'tab' else return indentation.inspect end singular = indentation.length == 1 "#{indentation.length} #{noun}#{'s' unless singular}" end
def inspect_obj(obj)
-
(String)
-
Parameters:
-
obj
(Object
) --
def inspect_obj(obj) case obj when String %Q!"#{obj.gsub(/[\x00-\x7F]+/) {|s| s.dump[1...-1]}}"! when Symbol ":#{inspect_obj(obj.to_s)}" else obj.inspect end end
def parse_haml_magic_comment(str)
-
((Boolean, String or nil))
-
def parse_haml_magic_comment(str) scanner = StringScanner.new(str.dup.force_encoding(Encoding::ASCII_8BIT)) bom = scanner.scan(/\xEF\xBB\xBF/n) return bom unless scanner.scan(/-\s*#\s*/n) if (coding = try_parse_haml_emacs_magic_comment(scanner)) return bom, coding end return bom unless scanner.scan(/.*?coding[=:]\s*([\w-]+)/in) return bom, scanner[1] end
def rails_xss_safe?
-
(Boolean)
-
def rails_xss_safe? false end
def silence_warnings
- Yield: - A block in which no output will be printed to STDERR
def silence_warnings the_real_stderr, $stderr = $stderr, StringIO.new yield ensure $stderr = the_real_stderr end
def try_parse_haml_emacs_magic_comment(scanner)
def try_parse_haml_emacs_magic_comment(scanner) pos = scanner.pos return unless scanner.scan(/.*?-\*-\s*/n) # From Ruby's parse.y return unless scanner.scan(/([^\s'":;]+)\s*:\s*("(?:\\.|[^"])*"|[^"\s;]+?)[\s;]*-\*-/n) name, val = scanner[1], scanner[2] return unless name =~ /(en)?coding/in val = $1 if val =~ /^"(.*)"$/n return val ensure scanner.pos = pos end
def unescape_interpolation(str, escape_html = nil)
def unescape_interpolation(str, escape_html = nil) res = ''.dup rest = Haml::Util.handle_interpolation str.dump do |scan| escapes = (scan[2].size - 1) / 2 char = scan[3] # '{', '@' or '$' res << scan.matched[0...-3 - escapes] if escapes % 2 == 1 res << "\##{char}" else interpolated = if char == '{' balance(scan, ?{, ?}, 1)[0][0...-1] else scan.scan(/\w+/) end content = eval("\"#{interpolated}\"") content = "#{char}#{content}" if char == '@' || char == '$' content = "Haml::Util.escape_html_safe((#{content}).to_s)" if escape_html res << "\#{#{content}}" end end res + rest end