if the content starts with multiple line breaks. if ( preg_match( '/^\s*\n\s*\n\s*/', $content ) ) { $this->end_tag( 'p' ); } // Split up the contents into paragraphs, separated by double line breaks. $paragraphs = preg_split( '/\s*\n\s*\n\s*/', $content ); $paragraphs = array_filter( $paragraphs, static function ( $paragraph ) { return '' !== trim( $paragraph ); } ); $paragraphs = array_values( $paragraphs ); if ( $paragraphs ) { if ( $this->is_inside( 'p' ) ) { $paragraph = array_shift( $paragraphs ); $paragraph = self::normalize_paragraph( $paragraph, $this->options['auto_br'] ); $this->output .= $paragraph; } foreach ( $paragraphs as $paragraph ) { $this->start_tag( 'p' ); $paragraph = ltrim( $paragraph ); $paragraph = self::normalize_paragraph( $paragraph, $this->options['auto_br'] ); $this->output .= $paragraph; } } // Close
if the content ends with multiple line breaks. if ( preg_match( '/\s*\n\s*\n\s*$/', $content ) ) { $this->end_tag( 'p' ); } // Cases where the content is a single line break. if ( preg_match( '/^\s*\n\s*$/', $content ) ) { $auto_br = $this->options['auto_br'] && $this->is_inside( 'p' ); $content = self::normalize_paragraph( $content, $auto_br ); $this->output .= $content; } } else { $auto_br = $this->options['auto_br'] && $this->has_parent( self::br_parent_elements ); $content = self::normalize_paragraph( $content, $auto_br ); $this->output .= $content; } } /** * Appends a start tag to the output property. * * @param string $tag A start tag. */ public function start_tag( $tag ) { list( $tag, $tag_name ) = self::normalize_start_tag( $tag ); if ( in_array( $tag_name, self::p_child_elements ) ) { if ( ! $this->is_inside( 'p' ) and ! $this->is_inside( self::p_child_elements ) and ! $this->has_parent( self::p_nonparent_elements ) ) { // Open
if it does not exist. $this->start_tag( 'p' ); } } elseif ( 'p' === $tag_name or in_array( $tag_name, self::p_parent_elements ) or in_array( $tag_name, self::p_nonparent_elements ) ) { // Close
if it exists. $this->end_tag( 'p' ); } if ( 'dd' === $tag_name or 'dt' === $tag_name ) { // Close
\s*<\/p>$/', '', $this->output ); } /** * Appends an HTML comment to the output property. * * @param string $tag An HTML comment. */ public function append_comment( $tag ) { $this->output .= $tag; } /** * Returns true if it is currently inside one of HTML elements specified * by tag names. * * @param string|array $tag_names A tag name or an array of tag names. */ public function is_inside( $tag_names ) { $tag_names = (array) $tag_names; foreach ( $this->stacked_elements as $element ) { if ( in_array( $element, $tag_names ) ) { return true; } } return false; } /** * Returns true if the parent node is one of HTML elements specified * by tag names. * * @param string|array $tag_names A tag name or an array of tag names. */ public function has_parent( $tag_names ) { $tag_names = (array) $tag_names; $parent = reset( $this->stacked_elements ); if ( false === $parent ) { return false; } return in_array( $parent, $tag_names ); } /** * Calculates the position of the next chunk based on the position and * length of the current chunk. * * @param array $chunk An associative array of the current chunk. * @return int The position of the next chunk. */ public static function calc_next_position( $chunk ) { return $chunk['position'] + strlen( $chunk['content'] ); } /** * Outputs a set of tabs to indent. * * @param int $level Indentation level. * @return string A series of tabs. */ public static function indent( $level ) { $level = (int) $level; if ( 0 < $level ) { return str_repeat( "\t", $level ); } return ''; } /** * Normalizes a start tag. * * @param string $tag A start tag or a tag name. * @return array An array includes the normalized start tag and tag name. */ public static function normalize_start_tag( $tag ) { if ( preg_match( '/<(.+?)[\s\/>]/', $tag, $matches ) ) { $tag_name = strtolower( $matches[1] ); } else { $tag_name = strtolower( $tag ); $tag = sprintf( '<%s>', $tag_name ); } if ( in_array( $tag_name, self::void_elements ) ) { // Normalize void element. $tag = preg_replace( '/\s*\/?>/', ' />', $tag ); } return array( $tag, $tag_name ); } /** * Normalizes a paragraph of text. * * @param string $paragraph A paragraph of text. * @param bool $auto_br Optional. If true, line breaks will be replaced * by a br element. * @return string The normalized paragraph. */ public static function normalize_paragraph( $paragraph, $auto_br = false ) { if ( $auto_br ) { $paragraph = preg_replace( '/\s*\n\s*/', "\n", $paragraph ); } $paragraph = preg_replace( '/[ ]+/', " ", $paragraph ); return $paragraph; } }