This file is indexed.

/usr/lib/ruby/vendor_ruby/html2haml/html.rb is in ruby-html2haml 1.0.1-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
require 'cgi'
require 'hpricot'
require 'html2haml/html/erb'

# Haml monkeypatches various Hpricot classes
# to add methods for conversion to Haml.
# @private
module Hpricot
  # @see Hpricot
  module Node
    # Whether this node has already been converted to Haml.
    # Only used for text nodes and elements.
    #
    # @return [Boolean]
    attr_accessor :converted_to_haml

    # Returns the Haml representation of the given node.
    #
    # @param tabs [Fixnum] The indentation level of the resulting Haml.
    # @option options (see Haml::HTML#initialize)
    def to_haml(tabs, options)
      return "" if converted_to_haml || to_s.strip.empty?
      text = uninterp(self.to_s)
      node = next_node
      while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
        node.converted_to_haml = true
        text << '#{' <<
          CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'

        if node.next_node.is_a?(::Hpricot::Text)
          node = node.next_node
          text << uninterp(node.to_s)
          node.converted_to_haml = true
        end

        node = node.next_node
      end
      return parse_text_with_interpolation(text, tabs)
    end

    private

    def erb_to_interpolation(text, options)
      return text unless options[:erb]
      text = CGI.escapeHTML(uninterp(text))
      %w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
      ::Hpricot::XML(text).children.inject("") do |str, elem|
        if elem.is_a?(::Hpricot::Text)
          str + CGI.unescapeHTML(elem.to_s)
        else # <haml:loud> element
          str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
        end
      end
    end

    def tabulate(tabs)
      '  ' * tabs
    end

    def uninterp(text)
      text.gsub('#{', '\#{') #'
    end

    def attr_hash
      attributes.to_hash
    end

    def parse_text(text, tabs)
      parse_text_with_interpolation(uninterp(text), tabs)
    end

    def parse_text_with_interpolation(text, tabs)
      text.strip!
      return "" if text.empty?

      text.split("\n").map do |line|
        line.strip!
        "#{tabulate(tabs)}#{'\\' if Haml::Parser::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
      end.join
    end
  end
end

# @private
HAML_TAGS = %w[haml:block haml:loud haml:silent]

HAML_TAGS.each do |t|
  Hpricot::ElementContent[t] = {}
  Hpricot::ElementContent.keys.each do |key|
    Hpricot::ElementContent[t][key.hash] = true
  end
end

Hpricot::ElementContent.keys.each do |k|
  HAML_TAGS.each do |el|
    val = Hpricot::ElementContent[k]
    val[el.hash] = true if val.is_a?(Hash)
  end
end

module Haml
  # Converts HTML documents into Haml templates.
  # Depends on [Hpricot](http://github.com/whymirror/hpricot) for HTML parsing.
  # If ERB conversion is being used, also depends on 
  # [Erubis](http://www.kuwata-lab.com/erubis) to parse the ERB
  # and [ruby_parser](http://parsetree.rubyforge.org/) to parse the Ruby code.
  #
  # Example usage:
  #
  #     Haml::HTML.new("<a href='http://google.com'>Blat</a>").render
  #       #=> "%a{:href => 'http://google.com'} Blat"
  class HTML
    # @param template [String, Hpricot::Node] The HTML template to convert
    # @option options :erb [Boolean] (false) Whether or not to parse
    #   ERB's `<%= %>` and `<% %>` into Haml's `=` and `-`
    # @option options :xhtml [Boolean] (false) Whether or not to parse
    #   the HTML strictly as XHTML
    def initialize(template, options = {})
      @options = options

      if template.is_a? Hpricot::Node
        @template = template
      else
        if template.is_a? IO
          template = template.read
        end

        template = Haml::Util.check_encoding(template) {|msg, line| raise Haml::Error.new(msg, line)}

        if @options[:erb]
          require 'html2haml/html/erb'
          template = ERB.compile(template)
        end

        method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
        @template = method.call(template.gsub('&', '&amp;'))
      end
    end

    # Processes the document and returns the result as a string
    # containing the Haml template.
    def render
      @template.to_haml(0, @options)
    end
    alias_method :to_haml, :render

    TEXT_REGEXP = /^(\s*).*$/

    # @see Hpricot
    # @private
    class ::Hpricot::Doc
      # @see Haml::HTML::Node#to_haml
      def to_haml(tabs, options)
        (children || []).inject('') {|s, c| s << c.to_haml(0, options)}
      end
    end

    # @see Hpricot
    # @private
    class ::Hpricot::XMLDecl
      # @see Haml::HTML::Node#to_haml
      def to_haml(tabs, options)
        "#{tabulate(tabs)}!!! XML\n"
      end
    end

    # @see Hpricot
    # @private
    class ::Hpricot::CData
      # @see Haml::HTML::Node#to_haml
      def to_haml(tabs, options)
        content = parse_text_with_interpolation(
          erb_to_interpolation(self.content, options), tabs + 1)
        "#{tabulate(tabs)}:cdata\n#{content}"
      end
    end

    # @see Hpricot
    # @private
    class ::Hpricot::DocType
      # @see Haml::HTML::Node#to_haml
      def to_haml(tabs, options)
        attrs = public_id.nil? ? ["", "", ""] :
          public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
        raise Haml::SyntaxError.new("Invalid doctype") if attrs == nil

        type, version, strictness = attrs.map { |a| a.downcase }
        if type == "html"
          version = ""
          strictness = "strict" if strictness == ""
        end

        if version == "1.0" || version.empty?
          version = nil
        end

        if strictness == 'transitional' || strictness.empty?
          strictness = nil
        end

        version = " #{version.capitalize}" if version
        strictness = " #{strictness.capitalize}" if strictness

        "#{tabulate(tabs)}!!!#{version}#{strictness}\n"
      end
    end

    # @see Hpricot
    # @private
    class ::Hpricot::Comment
      # @see Haml::HTML::Node#to_haml
      def to_haml(tabs, options)
        content = self.content
        if content =~ /\A(\[[^\]]+\])>(.*)<!\[endif\]\z/m
          condition = $1
          content = $2
        end

        if content.include?("\n")
          "#{tabulate(tabs)}/#{condition}\n#{parse_text(content, tabs + 1)}"
        else
          "#{tabulate(tabs)}/#{condition} #{content.strip}\n"
        end
      end
    end

    # @see Hpricot
    # @private
    class ::Hpricot::Elem
      # @see Haml::HTML::Node#to_haml
      def to_haml(tabs, options)
        return "" if converted_to_haml
        if name == "script" &&
            (attr_hash['type'].nil? || attr_hash['type'] == "text/javascript") &&
            (attr_hash.keys - ['type']).empty?
          return to_haml_filter(:javascript, tabs, options)
        elsif name == "style" &&
            (attr_hash['type'].nil? || attr_hash['type'] == "text/css") &&
            (attr_hash.keys - ['type']).empty?
          return to_haml_filter(:css, tabs, options)
        end

        output = tabulate(tabs)
        if options[:erb] && name[0...5] == 'haml:'
          case name[5..-1]
          when "loud"
            lines = CGI.unescapeHTML(inner_text).split("\n").
              map {|s| s.rstrip}.reject {|s| s.strip.empty?}
            lines.first.gsub!(/^[ \t]*/, "= ")

            if lines.size > 1 # Multiline script block
              # Normalize the indentation so that the last line is the base
              indent_str = lines.last[/^[ \t]*/]
              indent_re = /^[ \t]{0,#{indent_str.count(" ") + 8 * indent_str.count("\t")}}/
              lines.map! {|s| s.gsub!(indent_re, '')}

              # Add an extra "  " to make it indented relative to "= "
              lines[1..-1].each {|s| s.gsub!(/^/, "  ")}

              # Add | at the end, properly aligned
              length = lines.map {|s| s.size}.max + 1
              lines.map! {|s| "%#{-length}s|" % s}

              if next_sibling && next_sibling.is_a?(Hpricot::Elem) && next_sibling.name == "haml:loud" &&
                  next_sibling.inner_text.split("\n").reject {|s| s.strip.empty?}.size > 1
                lines << "-#"
              end
            end
            return lines.map {|s| output + s + "\n"}.join
          when "silent"
            return CGI.unescapeHTML(inner_text).split("\n").map do |line|
              next "" if line.strip.empty?
              "#{output}- #{line.strip}\n"
            end.join
          when "block"
            return render_children("", tabs, options)
          end
        end

        if self.next && self.next.text? && self.next.content =~ /\A[^\s]/
          if self.previous.nil? || self.previous.text? &&
              (self.previous.content =~ /[^\s]\Z/ ||
               self.previous.content =~ /\A\s*\Z/ && self.previous.previous.nil?)
            nuke_outer_whitespace = true
          else
            output << "= succeed #{self.next.content.slice!(/\A[^\s]+/).dump} do\n"
            tabs += 1
            output << tabulate(tabs)
          end
        end

        output << "%#{name}" unless name == 'div' &&
          (static_id?(options) ||
           static_classname?(options) &&
           attr_hash['class'].split(' ').any?(&method(:haml_css_attr?)))

        if attr_hash
          if static_id?(options)
            output << "##{attr_hash['id']}"
            remove_attribute('id')
          end
          if static_classname?(options)
            leftover = attr_hash['class'].split(' ').reject do |c|
              next unless haml_css_attr?(c)
              output << ".#{c}"
            end
            remove_attribute('class')
            set_attribute('class', leftover.join(' ')) unless leftover.empty?
          end
          output << haml_attributes(options) if attr_hash.length > 0
        end

        output << ">" if nuke_outer_whitespace
        output << "/" if empty? && !etag

        if children && children.size == 1
          child = children.first
          if child.is_a?(::Hpricot::Text)
            if !child.to_s.include?("\n")
              text = child.to_haml(tabs + 1, options)
              return output + " " + text.lstrip.gsub(/^\\/, '') unless text.chomp.include?("\n") || text.empty?
              return output + "\n" + text
            elsif ["pre", "textarea"].include?(name) ||
                (name == "code" && parent.is_a?(::Hpricot::Elem) && parent.name == "pre")
              return output + "\n#{tabulate(tabs + 1)}:preserve\n" +
                innerText.gsub(/^/, tabulate(tabs + 2))
            end
          elsif child.is_a?(::Hpricot::Elem) && child.name == "haml:loud"
            return output + child.to_haml(tabs + 1, options).lstrip
          end
        end

        render_children(output + "\n", tabs, options)
      end

      private

      def render_children(so_far, tabs, options)
        (self.children || []).inject(so_far) do |output, child|
          output + child.to_haml(tabs + 1, options)
        end
      end

      def dynamic_attributes
        @dynamic_attributes ||= begin
          Hash[attr_hash.map do |name, value|
            next if value.empty?
            full_match = nil
            ruby_value = value.gsub(%r{<haml:loud>\s*(.+?)\s*</haml:loud>}) do
              full_match = $`.empty? && $'.empty?
              CGI.unescapeHTML(full_match ? $1: "\#{#{$1}}")
            end
            next if ruby_value == value
            [name, full_match ? ruby_value : %("#{ruby_value}")]
          end]
        end
      end

      def to_haml_filter(filter, tabs, options)
        content =
          if children.first.is_a?(::Hpricot::CData)
            children.first.content
          else
            CGI.unescapeHTML(self.innerText)
          end

        content = erb_to_interpolation(content, options)
        content.gsub!(/\A\s*\n(\s*)/, '\1')
        original_indent = content[/\A(\s*)/, 1]
        if content.split("\n").all? {|l| l.strip.empty? || l =~ /^#{original_indent}/}
          content.gsub!(/^#{original_indent}/, tabulate(tabs + 1))
        else
          # Indentation is inconsistent. Strip whitespace from start and indent all
          # to ensure valid Haml.
          content.lstrip!
          content.gsub!(/^/, tabulate(tabs + 1))
        end

        content.rstrip!
        content << "\n"

        "#{tabulate(tabs)}:#{filter}\n#{content}"
      end

      def static_attribute?(name, options)
        attr_hash[name] && !dynamic_attribute?(name, options)
      end

      def dynamic_attribute?(name, options)
        options[:erb] and dynamic_attributes.key?(name)
      end

      def static_id?(options)
        static_attribute?('id', options) && haml_css_attr?(attr_hash['id'])
      end

      def static_classname?(options)
        static_attribute?('class', options)
      end

      def haml_css_attr?(attr)
        attr =~ /^[-:\w]+$/
      end

      # Returns a string representation of an attributes hash
      # that's prettier than that produced by Hash#inspect
      def haml_attributes(options)
        attrs = attr_hash.sort.map do |name, value|
          haml_attribute_pair(name, value, options)
        end
        if options[:html_style_attributes]
          "(#{attrs.join(' ')})"
        else
          "{#{attrs.join(', ')}}"
        end
      end

      # Returns the string representation of a single attribute key value pair
      def haml_attribute_pair(name, value, options)
        value = dynamic_attribute?(name, options) ? dynamic_attributes[name] : value.inspect
        if options[:html_style_attributes]
          "#{name}=#{value}"
        else
          name = name.index(/\W/) ? name.inspect : ":#{name}"
          "#{name} => #{value}"
        end
      end
    end
  end
end