FCKeditor/function removeHTMLtags
NOTE: Copy from editor. There are '>' tags that should be '>' tags.
function removeHTMLtags( $text, $processCallback = null, $args = array() ) { global $wgUseTidy, $wgUserHtml; $fname = 'Parser::removeHTMLtags'; wfProfileIn( $fname ); if( $wgUserHtml ) { $htmlpairs = array( # Tags that must be closed 'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's', 'strike', 'strong', 'tt', 'var', 'div', 'center', 'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre', 'ruby', 'rt' , 'rb' , 'rp', 'p', 'span' ); $htmlsingle = array( 'br', 'hr', 'li', 'dt', 'dd' ); $htmlsingleonly = array( # Elements that cannot have close tags 'br', 'hr' ); $htmlnest = array( # Tags that can be nested--?? 'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul', 'dl', 'font', 'big', 'small', 'sub', 'sup', 'span' ); $tabletags = array( # Can only appear inside table 'td', 'th', 'tr' , 'tbody' # patch for fck editor ); } else { $htmlpairs = array(); $htmlsingle = array(); $htmlnest = array(); $tabletags = array(); } $htmlsingle = array_merge( $tabletags, $htmlsingle ); $htmlelements = array_merge( $htmlsingle, $htmlpairs ); # Remove HTML comments $text = Sanitizer::removeHTMLcomments( $text ); $bits = explode( '<', $text ); $text = array_shift( $bits ); if(!$wgUseTidy) { $tagstack = array(); $tablestack = array(); foreach ( $bits as $x ) { $prev = error_reporting( E_ALL & ~( E_NOTICE | E_WARNING ) ); preg_match( '/^(\\/?)(\\w+)([^>]*?)(\\/{0,1}>)([^<]*)$/', $x, $regs ); list( $qbar, $slash, $t, $params, $brace, $rest ) = $regs; error_reporting( $prev ); $badtag = 0 ; if ( in_array( $t = strtolower( $t ), $htmlelements ) ) { # Check our stack if ( $slash ) { # Closing a tag... if( in_array( $t, $htmlsingleonly ) ) { $badtag = 1; } elseif ( ( $ot = @array_pop( $tagstack ) ) != $t ) { @array_push( $tagstack, $ot ); $badtag = 1; } else { if ( $t == 'table' ) { $tagstack = array_pop( $tablestack ); } $newparams = ''; } } else { # Keep track for later if ( in_array( $t, $tabletags ) && ! in_array( 'table', $tagstack ) ) { $badtag = 1; } else if ( in_array( $t, $tagstack ) && ! in_array ( $t , $htmlnest ) ) { $badtag = 1 ; } elseif( in_array( $t, $htmlsingleonly ) ) { # Hack to force empty tag for uncloseable elements $brace = '/>'; } else { if ( $t == 'table' ) { array_push( $tablestack, $tagstack ); $tagstack = array(); } array_push( $tagstack, $t ); } # Replace any variables or template parameters with # plaintext results. if( is_callable( $processCallback ) ) { call_user_func_array( $processCallback, array( &$params, $args ) ); } # Strip non-approved attributes from the tag $newparams = Sanitizer::fixTagAttributes( $params, $t ); } if ( ! $badtag ) { $rest = str_replace( '>', '>', $rest ); $close = ( $brace == '/>' ) ? ' /' : ''; $text .= "<$slash$t$newparams$close>$rest"; continue; } } $text .= '<' . str_replace( '>', '>', $x); } # Close off any remaining tags while ( is_array( $tagstack ) && ($t = array_pop( $tagstack )) ) { $text .= "</$t>\n"; if ( $t == 'table' ) { $tagstack = array_pop( $tablestack ); } } } else { # this might be possible using tidy itself foreach ( $bits as $x ) { preg_match( '/^(\\/?)(\\w+)([^>]*?)(\\/{0,1}>)([^<]*)$/', $x, $regs ); @list( $qbar, $slash, $t, $params, $brace, $rest ) = $regs; if ( in_array( $t = strtolower( $t ), $htmlelements ) ) { if( is_callable( $processCallback ) ) { call_user_func_array( $processCallback, array( &$params, $args ) ); } $newparams = Sanitizer::fixTagAttributes( $params, $t ); $rest = str_replace( '>', '>', $rest ); $text .= "<$slash$t$newparams$brace$rest"; } else { $text .= '<' . str_replace( '>', '>', $x); } } } wfProfileOut( $fname ); return $text; }