def _element(tag_name, *args, &block)
      if args.length > 2
        raise ArgumentError, "too many args"
      end
      attributes, value = nil, nil
      arg0 = args[0]
      if arg0.is_a?(Hash)
        attributes = arg0
      else
        value = arg0
        arg1 = args[1]
        if arg1.is_a?(Hash)
          attributes = arg1
        end
      end

      if block && value
        raise ArgumentError, "You can't pass both a block and a value to #{tag_name} -- please choose one."
      end

      attributes ||= {}
      promise = if !value.nil?
        Promise.new(output, tag_name,  attributes, false, newliney?(tag_name)) do
          if value.is_a? AbstractWidget
            widget value
          else
            text value
          end
        end
      elsif block
        Promise.new(output, tag_name, attributes, false, newliney?(tag_name), &block)
      else
        Promise.new(output, tag_name, attributes, false, newliney?(tag_name))
      end
      promise._render
      promise
    end
def _element(tag_name, *args, &block)
      if args.length > 2
        raise ArgumentError, "too many args"
      end
      attributes, value = nil, nil
      arg0 = args[0]
      if arg0.is_a?(Hash)
        attributes = arg0
      else
        value = arg0
        arg1 = args[1]
        if arg1.is_a?(Hash)
          attributes = arg1
        end
      end

      if block && value
        raise ArgumentError, "You can't pass both a block and a value to #{tag_name} -- please choose one."
      end

      attributes ||= {}
      promise = if !value.nil?
        Promise.new(output, tag_name,  attributes, false, newliney?(tag_name)) do
          if value.is_a? AbstractWidget
            widget value
          else
            text value
          end
        end
      elsif block
        Promise.new(output, tag_name, attributes, false, newliney?(tag_name), &block)
      else
        Promise.new(output, tag_name, attributes, false, newliney?(tag_name))
      end
      promise._render
      promise
    end
moved to Promise
 # Emits an open tag, comprising '<', tag name, optional attributes, and '>'
 def open_tag(promise)
   output.newline if newliney?(promise._tag_name) && !output.at_line_start?
   output << promise._open_tag
   output.indent
 end

 # Emits a close tag, consisting of '<', '/', tag name, and '>'
 def close_tag(promise)
   output.undent
   output << promise._close_tag
   if newliney?(promise._tag_name)
     output.newline
   end
 end

 def inside_tag value, block
   if block
     block.call
   else
     text value
   end
 end