require "htmlbeautifier/parser" require "htmlbeautifier/ruby_indenter" module HtmlBeautifier class Builder DEFAULT_OPTIONS = { indent: " ", initial_level: 0, stop_on_errors: false, keep_blank_lines: 0 } def initialize(output, options = {}) options = DEFAULT_OPTIONS.merge(options) @tab = options[:indent] @stop_on_errors = options[:stop_on_errors] @level = options[:initial_level] @keep_blank_lines = options[:keep_blank_lines] @new_line = false @empty = true @ie_cc_levels = [] @output = output @embedded_indenter = RubyIndenter.new end private def error(text) return unless @stop_on_errors raise text end def indent @level += 1 end def outdent error "Extraneous closing tag" if @level == 0 @level = [@level - 1, 0].max end def emit(*strings) @output << "\n" if @new_line && !@empty @output << (@tab * @level) if @new_line @output << strings.join("") @new_line = false @empty = false end def new_line @new_line = true end def embed(opening, code, closing) lines = code.split(%r{\n}).map(&:strip) outdent if @embedded_indenter.outdent?(lines) emit opening, code, closing indent if @embedded_indenter.indent?(lines) end def foreign_block(opening, code, closing) emit opening emit_reindented_block_content code unless code.strip.empty? emit closing end def emit_reindented_block_content(code) lines = code.strip.split(%r{\n}) indentation = foreign_block_indentation(code) indent new_line lines.each do |line| emit line.rstrip.sub(%r{^#{indentation}}, "") new_line end outdent end def foreign_block_indentation(code) code.split(%r{\n}).find { |ln| !ln.strip.empty? }[%r{^\s+}] end def preformatted_block(opening, content, closing) new_line emit opening, content, closing new_line end def standalone_element(e) emit e new_line if e =~ %r{^