<commit_before>module Erector
  # A proxy to an IO object that adds methods to add xml. 
  class Doc

    NON_NEWLINEY = {'i' => true, 'b' => true, 'small' => true,
      'img' => true, 'span' => true, 'a' => true,
      'input' => true, 'textarea' => true, 'button' => true, 'select' => true
    }
    
    SPACES_PER_INDENT = 2
    
    attr_reader :output
    attr_accessor :add_newlines

    def initialize(output, options = {})
      @output = output
      @at_start_of_line = true
      @indent = 0
      @add_newlines = options[:add_newlines]
    end

    def newliney(tag_name)
      if @add_newlines
        !NON_NEWLINEY.include?(tag_name)
      else
        false
      end
    end
  
    def open_tag(tag_name, attributes={})
      indent_for_open_tag(tag_name)
      @indent += SPACES_PER_INDENT

      output.print "<#{tag_name}#{format_attributes(attributes)}>"
      @at_start_of_line = false
    end

    def text(value)
      output.print(value.html_escape)
      @at_start_of_line = false
      nil
    end

    def close_tag(tag_name)
      @indent -= SPACES_PER_INDENT
      indent()

      output.print("</#{tag_name}>")

      if newliney(tag_name)
        output.print "\n"
        @at_start_of_line = true
      end
    end
    
    def indent_for_open_tag(tag_name)
      if !@at_start_of_line && newliney(tag_name)
        output.print "\n"
        @at_start_of_line = true
      end

      indent()
    end
    
    def indent()
      if @at_start_of_line
        output.print " " * @indent
      end
    end

    def empty_element(tag_name, attributes={})
      indent_for_open_tag(tag_name)

      output.print "<#{tag_name}#{format_attributes(attributes)} />"

      if newliney(tag_name)
        output.print "\n"
        @at_start_of_line = true
      end
    end

    def instruct(attributes={:version => "1.0", :encoding => "UTF-8"})
      output.print "<?xml#{format_sorted(sort_for_xml_declaration(attributes))}?>"
    end

    def to_s
      output.string
    end

    protected
    def method_missing(method_name, *args, &blk)
      output.__send__(method_name, *args, &blk)
    rescue NoMethodError => e
      raise NoMethodError, "undefined method `#{method_name}' for #{inspect}"
    end

    def format_attributes(attributes)
      return "" if !attributes || attributes.empty?
      return format_sorted(sorted(attributes))
    end

    def format_sorted(sorted)
      results = ['']
      sorted.each do |key, value|
        if value
          if value.is_a?(Array)
            value = [value].flatten.join(' ')
          end
          results << "#{key}=\"#{value.html_escape}\""
        end
      end
      return results.join(' ')
    end

    def sorted(attributes)
      stringized = []
      attributes.each do |key, value|
        stringized << [key.to_s, value]
      end
      return stringized.sort
    end

    def sort_for_xml_declaration(attributes)
      # correct order is "version, encoding, standalone" (XML 1.0 section 2.8).
      # But we only try to put version before encoding for now.
      stringized = []
      attributes.each do |key, value|
        stringized << [key.to_s, value]
      end
      return stringized.sort{|a, b| b <=> a}
    end
  end
end
<commit_msg>Rename Doc#doc to #output.<commit_after>module Erector
  # A proxy to an IO object that adds methods to add xml.
  class Doc

    NON_NEWLINEY = {'i' => true, 'b' => true, 'small' => true,
      'img' => true, 'span' => true, 'a' => true,
      'input' => true, 'textarea' => true, 'button' => true, 'select' => true
    }

    SPACES_PER_INDENT = 2

    attr_reader :output
    attr_accessor :add_newlines

    def initialize(output, options = {})
      @output = output
      @at_start_of_line = true
      @indent = 0
      @add_newlines = options[:add_newlines]
    end

    def newliney(tag_name)
      if @add_newlines
        !NON_NEWLINEY.include?(tag_name)
      else
        false
      end
    end

    def open_tag(tag_name, attributes={})
      indent_for_open_tag(tag_name)
      @indent += SPACES_PER_INDENT

      output.print "<#{tag_name}#{format_attributes(attributes)}>"
      @at_start_of_line = false
    end

    def text(value)
      output.print(value.html_escape)
      @at_start_of_line = false
      nil
    end

    def close_tag(tag_name)
      @indent -= SPACES_PER_INDENT
      indent()

      output.print("</#{tag_name}>")

      if newliney(tag_name)
        output.print "\n"
        @at_start_of_line = true
      end
    end

    def indent_for_open_tag(tag_name)
      if !@at_start_of_line && newliney(tag_name)
        output.print "\n"
        @at_start_of_line = true
      end

      indent()
    end

    def indent()
      if @at_start_of_line
        output.print " " * @indent
      end
    end

    def empty_element(tag_name, attributes={})
      indent_for_open_tag(tag_name)

      output.print "<#{tag_name}#{format_attributes(attributes)} />"

      if newliney(tag_name)
        output.print "\n"
        @at_start_of_line = true
      end
    end

    def instruct(attributes={:version => "1.0", :encoding => "UTF-8"})
      output.print "<?xml#{format_sorted(sort_for_xml_declaration(attributes))}?>"
    end

    def to_s
      output.string
    end

    protected
    def method_missing(method_name, *args, &blk)
      output.__send__(method_name, *args, &blk)
    rescue NoMethodError => e
      raise NoMethodError, "undefined method `#{method_name}' for #{inspect}"
    end

    def format_attributes(attributes)
      return "" if !attributes || attributes.empty?
      return format_sorted(sorted(attributes))
    end

    def format_sorted(sorted)
      results = ['']
      sorted.each do |key, value|
        if value
          if value.is_a?(Array)
            value = [value].flatten.join(' ')
          end
          results << "#{key}=\"#{value.html_escape}\""
        end
      end
      return results.join(' ')
    end

    def sorted(attributes)
      stringized = []
      attributes.each do |key, value|
        stringized << [key.to_s, value]
      end
      return stringized.sort
    end

    def sort_for_xml_declaration(attributes)
      # correct order is "version, encoding, standalone" (XML 1.0 section 2.8).
      # But we only try to put version before encoding for now.
      stringized = []
      attributes.each do |key, value|
        stringized << [key.to_s, value]
      end
      return stringized.sort{|a, b| b <=> a}
    end
  end
end

{'fraction_non_alphanumeric': 0.11425479282622139, 'fraction_numerical': 0.0027829313543599257, 'mean_word_length': 2.3208418891170433, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1156839', 'n_tokens_mistral': 2152, 'n_tokens_neox': 2113, 'n_words': 493}