# File lib/html5/tokenizer.rb, line 299
    def tag_open_state
      data = @stream.char
      if @content_model_flag == :PCDATA
        if data == "!"
          @state = :markup_declaration_open_state
        elsif data == "/"
          @state = :close_tag_open_state
        elsif data != :EOF and ASCII_LETTERS.include? data
          @current_token = {:type => :StartTag, :name => data, :data => []}
          @state = :tag_name_state
        elsif data == ">"
          # XXX In theory it could be something besides a tag name. But
          # do we really care?
          @token_queue << {:type => :ParseError, :data =>       "expected-tag-name-but-got-right-bracket"}
          @token_queue << {:type => :Characters, :data => "<>"}
          @state = :data_state
        elsif data == "?"
          # XXX In theory it could be something besides a tag name. But
          # do we really care?
          @token_queue.push({:type => :ParseError, :data => "expected-tag-name-but-got-question-mark"})
          @stream.unget(data)
          @state = :bogus_comment_state
        else
          # XXX
          @token_queue << {:type => :ParseError, :data => "expected-tag-name"}
          @token_queue << {:type => :Characters, :data => "<"}
          @stream.unget(data)
          @state = :data_state
        end
      else
        # We know the content model flag is set to either RCDATA or CDATA
        # now because this state can never be entered with the PLAINTEXT
        # flag.
        if data == "/"
          @state = :close_tag_open_state
        else
          @token_queue << {:type => :Characters, :data => "<"}
          @stream.unget(data)
          @state = :data_state
        end
      end
      return true
    end