Title: WP_HTML_Processor::step
Published: November 8, 2023
Last modified: August 20, 2026

---

# WP_HTML_Processor::step( string $node_to_process = self::PROCESS_NEXT_NODE ): bool

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#description)
    - [See also](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#see-also)
 * [Parameters](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#wp--skip-link--target)

This function’s access is marked private. This means it is not intended for use 
by plugin or theme developers, only by core. It is listed here for completeness.

Steps through the HTML document and stop at the next tag, if any.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#description)󠁿

This is an internal method. The relevant public methods are [WP_HTML_Processor::next_tag()](https://developer.wordpress.org/reference/classes/WP_HTML_Processor/next_tag/)
and [WP_HTML_Processor::next_token()](https://developer.wordpress.org/reference/classes/WP_HTML_Processor/next_token/).

### 󠀁[See also](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#see-also)󠁿

 * [WP_HTML_Processor::PROCESS_NEXT_NODE](https://developer.wordpress.org/reference/classes/wp_html_processor/PROCESS_NEXT_NODE/)
 * [WP_HTML_Processor::REPROCESS_CURRENT_NODE](https://developer.wordpress.org/reference/classes/wp_html_processor/REPROCESS_CURRENT_NODE/)

## 󠀁[Parameters](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#parameters)󠁿

 `$node_to_process`stringoptional

Whether to parse the next node or reprocess the current node.

Default:`self::PROCESS_NEXT_NODE`

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#return)󠁿

 bool Whether a tag was matched.

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#source)󠁿

    ```php
    public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool {
    	// Refuse to proceed if there was a previous error.
    	if ( null !== $this->last_error ) {
    		return false;
    	}

    	if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) {
    		/*
    		 * Void elements still hop onto the stack of open elements even though
    		 * there's no corresponding closing tag. This is important for managing
    		 * stack-based operations such as "navigate to parent node" or checking
    		 * on an element's breadcrumbs.
    		 *
    		 * When moving on to the next node, therefore, if the bottom-most element
    		 * on the stack is a void element, it must be closed.
    		 */
    		$top_node = $this->state->stack_of_open_elements->current_node();
    		if ( isset( $top_node ) && ! $this->expects_closer( $top_node ) ) {
    			$this->state->stack_of_open_elements->pop();
    		}
    	}

    	if ( self::PROCESS_NEXT_NODE === $node_to_process ) {
    		parent::next_token();
    		if ( WP_HTML_Tag_Processor::STATE_TEXT_NODE === $this->parser_state ) {
    			parent::subdivide_text_appropriately();
    		}
    	}

    	// Finish stepping when there are no more tokens in the document.
    	if (
    		WP_HTML_Tag_Processor::STATE_INCOMPLETE_INPUT === $this->parser_state ||
    		WP_HTML_Tag_Processor::STATE_COMPLETE === $this->parser_state
    	) {
    		return false;
    	}

    	$adjusted_current_node = $this->get_adjusted_current_node();
    	$is_closer             = $this->is_tag_closer();
    	$is_start_tag          = WP_HTML_Tag_Processor::STATE_MATCHED_TAG === $this->parser_state && ! $is_closer;
    	$token_name            = $this->get_token_name();

    	if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) {
    		try {
    			$bookmark_name = $this->bookmark_token();
    		} catch ( Exception $e ) {
    			if ( self::ERROR_EXCEEDED_MAX_BOOKMARKS === $this->last_error ) {
    				return false;
    			}
    			throw $e;
    		}

    		$this->state->current_token = new WP_HTML_Token(
    			$bookmark_name,
    			$token_name,
    			$this->has_self_closing_flag(),
    			$this->release_internal_bookmark_on_destruct
    		);
    	}

    	$parse_in_current_insertion_mode = (
    		0 === $this->state->stack_of_open_elements->count() ||
    		'html' === $adjusted_current_node->namespace ||
    		(
    			'math' === $adjusted_current_node->integration_node_type &&
    			(
    				( $is_start_tag && ! in_array( $token_name, array( 'MGLYPH', 'MALIGNMARK' ), true ) ) ||
    				'#text' === $token_name
    			)
    		) ||
    		(
    			'math' === $adjusted_current_node->namespace &&
    			'ANNOTATION-XML' === $adjusted_current_node->node_name &&
    			$is_start_tag && 'SVG' === $token_name
    		) ||
    		(
    			'html' === $adjusted_current_node->integration_node_type &&
    			( $is_start_tag || '#text' === $token_name )
    		)
    	);

    	try {
    		if ( ! $parse_in_current_insertion_mode ) {
    			return $this->step_in_foreign_content();
    		}

    		switch ( $this->state->insertion_mode ) {
    			case WP_HTML_Processor_State::INSERTION_MODE_INITIAL:
    				return $this->step_initial();

    			case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML:
    				return $this->step_before_html();

    			case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD:
    				return $this->step_before_head();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD:
    				return $this->step_in_head();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT:
    				return $this->step_in_head_noscript();

    			case WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD:
    				return $this->step_after_head();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_BODY:
    				return $this->step_in_body();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE:
    				return $this->step_in_table();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT:
    				return $this->step_in_table_text();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION:
    				return $this->step_in_caption();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP:
    				return $this->step_in_column_group();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY:
    				return $this->step_in_table_body();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW:
    				return $this->step_in_row();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL:
    				return $this->step_in_cell();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE:
    				return $this->step_in_template();

    			case WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY:
    				return $this->step_after_body();

    			case WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET:
    				return $this->step_in_frameset();

    			case WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET:
    				return $this->step_after_frameset();

    			case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY:
    				return $this->step_after_after_body();

    			case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET:
    				return $this->step_after_after_frameset();

    			// This should be unreachable but PHP doesn't have total type checking on switch.
    			default:
    				$this->bail( "Unaware of the requested parsing mode: '{$this->state->insertion_mode}'." );
    		}
    	} catch ( WP_HTML_Unsupported_Exception $e ) {
    		/*
    		 * Exceptions are used in this class to escape deep call stacks that
    		 * otherwise might involve messier calling and return conventions.
    		 */
    		return false;
    	} catch ( Exception $e ) {
    		if ( self::ERROR_EXCEEDED_MAX_BOOKMARKS === $this->last_error ) {
    			return false;
    		}
    		// Rethrow any other exceptions for higher-level handling.
    		throw $e;
    	}
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/html-api/class-wp-html-processor.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.1/src/wp-includes/html-api/class-wp-html-processor.php#L1020)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.1/src/wp-includes/html-api/class-wp-html-processor.php#L1020-L1184)

## 󠀁[Related](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#related)󠁿

| Uses | Description | 
| [WP_HTML_Tag_Processor::subdivide_text_appropriately()](https://developer.wordpress.org/reference/classes/wp_html_tag_processor/subdivide_text_appropriately/)`wp-includes/html-api/class-wp-html-tag-processor.php` |

Subdivides a matched text node, splitting NULL byte sequences and decoded whitespace as distinct nodes prefixes.

  | 
| [WP_HTML_Processor::get_token_name()](https://developer.wordpress.org/reference/classes/wp_html_processor/get_token_name/)`wp-includes/html-api/class-wp-html-processor.php` |

Returns the node name represented by the token.

  | 
| [WP_HTML_Processor::has_self_closing_flag()](https://developer.wordpress.org/reference/classes/wp_html_processor/has_self_closing_flag/)`wp-includes/html-api/class-wp-html-processor.php` |

Indicates if the currently matched tag contains the self-closing flag.

  | 
| [WP_HTML_Processor::expects_closer()](https://developer.wordpress.org/reference/classes/wp_html_processor/expects_closer/)`wp-includes/html-api/class-wp-html-processor.php` |

Indicates if the currently-matched node expects a closing token, or if it will self-close on the next step.

  | 
| [WP_HTML_Processor::is_tag_closer()](https://developer.wordpress.org/reference/classes/wp_html_processor/is_tag_closer/)`wp-includes/html-api/class-wp-html-processor.php` |

Indicates if the current tag token is a tag closer.

  | 
| [WP_HTML_Tag_Processor::next_token()](https://developer.wordpress.org/reference/classes/wp_html_tag_processor/next_token/)`wp-includes/html-api/class-wp-html-tag-processor.php` |

Finds the next token in the HTML document.

  | 
| [WP_HTML_Token::__construct()](https://developer.wordpress.org/reference/classes/wp_html_token/__construct/)`wp-includes/html-api/class-wp-html-token.php` |

Constructor – creates a reference to a token in some external HTML string.

  |

[Show 2 more](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#)

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_html_processor/step/?output_format=md#changelog)󠁿

| Version | Description | 
| [6.4.0](https://developer.wordpress.org/reference/since/6.4.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_html_processor%2Fstep%2F)
before being able to contribute a note or feedback.