RemexHtml/Tokenizer/Tokenizer.php
protected function handleAttribsAndClose( $state, $tagName, $isEndTag, $startPos ) {
		$attribStartPos = $this->pos;
		$attribs = $this->consumeAttribs();
		$pos = $this->pos;

		// Literal characters are emitted on EOF or "anything else" from the
		// end tag substates of the text states.
		// (spec ref 8.2.4 sections 11-19, 25-27)
		$isDataState = $state === self::STATE_DATA;
		$isLiteral = $attribStartPos === $pos && !$isDataState;

		if ( $pos >= $this->length ) {
			$this->error( 'unexpected end of file inside tag' );
			if ( $isLiteral ) {
				$this->listener->characters( $this->text,
					$startPos, $this->length - $startPos,
					$startPos, $this->length - $startPos );
			}
			return self::STATE_EOF;
		}
		if ( $isEndTag && !$this->ignoreErrors && $attribs->count() ) {
			$this->error( 'end tag has an attribute' );
		}

		if ( $this->text[$pos] === '/' && $this->text[$pos + 1] === '>' ) {
			$pos += 2;
			$selfClose = true;
		} elseif ( $this->text[$pos] === '>' ) {
			$pos++;
			$selfClose = false;
		} elseif ( $isLiteral ) {
			$this->listener->characters( $this->text,
				$startPos, $attribStartPos - $startPos,
				$startPos, $attribStartPos - $startPos );
			return $state;
		} else {
			$this->fatal( 'failed to find an already-matched ">"' );
		}
		$this->pos = $pos;
		if ( $isEndTag ) {
			if ( $selfClose ) {
				$this->error( 'self-closing end tag' );
			}
			$this->listener->endTag( $tagName, $startPos, $pos - $startPos );
		} else {
			$this->listener->startTag( $tagName, $attribs, $selfClose,
				$startPos, $pos - $startPos );
		}
		return self::STATE_DATA;
	}
protected function handleAttribsAndClose( $state, $tagName, $isEndTag, $startPos ) {
		$attribStartPos = $this->pos;
		$attribs = $this->consumeAttribs();
		$pos = $this->pos;

		// Literal characters are emitted on EOF or "anything else" from the
		// end tag substates of the text states.
		// (spec ref 8.2.4 sections 11-19, 25-27)
		$isDataState = $state === self::STATE_DATA;
		$isLiteral = $attribStartPos === $pos && !$isDataState;

		if ( $pos >= $this->length ) {
			$this->error( 'unexpected end of file inside tag' );
			if ( $isLiteral ) {
				$this->listener->characters( $this->text,
					$startPos, $this->length - $startPos,
					$startPos, $this->length - $startPos );
			}
			return self::STATE_EOF;
		}
		if ( $isEndTag && !$this->ignoreErrors && $attribs->count() ) {
			$this->error( 'end tag has an attribute' );
		}

		if ( $this->text[$pos] === '/' && $this->text[$pos + 1] === '>' ) {
			$pos += 2;
			$selfClose = true;
		} elseif ( $this->text[$pos] === '>' ) {
			$pos++;
			$selfClose = false;
		} elseif ( $isLiteral ) {
			$this->listener->characters( $this->text,
				$startPos, $attribStartPos - $startPos,
				$startPos, $attribStartPos - $startPos );
			return $state;
		} else {
			$this->fatal( 'failed to find an already-matched ">"' );
		}
		$this->pos = $pos;
		if ( $isEndTag ) {
			if ( $selfClose ) {
				$this->error( 'self-closing end tag' );
			}
			$this->listener->endTag( $tagName, $startPos, $pos - $startPos );
		} else {
			$this->listener->startTag( $tagName, $attribs, $selfClose,
				$startPos, $pos - $startPos );
		}
		return self::STATE_DATA;
	}
protected function handleAttribsAndClose ( $ state , $ tagName , $ isEndTag , $ startPos ) { $ attribStartPos = $ this -> pos ; $ attribs = $ this -> consumeAttribs ( ) ; $ pos = $ this -> pos ; // Literal characters are emitted on EOF or "anything else" from the // end tag substates of the text states. // (spec ref 8.2.4 sections 11-19, 25-27) $ isDataState = $ state === self :: STATE_DATA ; $ isLiteral = $ attribStartPos === $ pos && ! $ isDataState ; if ( $ pos >= $ this -> length ) { $ this -> error ( 'unexpected end of file inside tag' ) ; if ( $ isLiteral ) { $ this -> listener -> characters ( $ this -> text , $ startPos , $ this -> length - $ startPos , $ startPos , $ this -> length - $ startPos ) ; } return self :: STATE_EOF ; } if ( $ isEndTag && ! $ this -> ignoreErrors && $ attribs -> count ( ) ) { $ this -> error ( 'end tag has an attribute' ) ; } if ( $ this -> text [ $ pos ] === '/' && $ this -> text [ $ pos + 1 ] === '>' ) { $ pos += 2 ; $ selfClose = true ; } elseif ( $ this -> text [ $ pos ] === '>' ) { $ pos ++ ; $ selfClose = false ; } elseif ( $ isLiteral ) { $ this -> listener -> characters ( $ this -> text , $ startPos , $ attribStartPos - $ startPos , $ startPos , $ attribStartPos - $ startPos ) ; return $ state ; } else { $ this -> fatal ( 'failed to find an already-matched ">"' ) ; } $ this -> pos = $ pos ; if ( $ isEndTag ) { if ( $ selfClose ) { $ this -> error ( 'self-closing end tag' ) ; } $ this -> listener -> endTag ( $ tagName , $ startPos , $ pos - $ startPos ) ; } else { $ this -> listener -> startTag ( $ tagName , $ attribs , $ selfClose , $ startPos , $ pos - $ startPos ) ; } return self :: STATE_DATA ; }
Consume attributes, and the closing bracket which follows attributes.
Emit the appropriate tag event, or in the case of broken attributes in
text states, emit characters.

@param int $state The current state
@param string $tagName The normalized tag name
@param bool $isEndTag True if this is an end tag, false if it is a start tag
@param int $startPos The input position of the start of the current tag.
@return int The next state
Consume attributes and the closing bracket which follows attributes . Emit the appropriate tag event or in the case of broken attributes in text states emit characters .