@@ -4017,7 +4017,104 @@ function wp_trim_excerpt( $text = '', $post = null ) {
40174017 * @param string $more_string The string shown within the more link.
40184018 */
40194019 $ excerpt_more = apply_filters ( 'excerpt_more ' , ' ' . '[…] ' );
4020- $ text = wp_trim_words ( $ text , $ excerpt_length , $ excerpt_more );
4020+
4021+ /**
4022+ * Filters the HTML tags allowed in an auto-generated post excerpt.
4023+ *
4024+ * @since 7.0.0
4025+ *
4026+ * @param string $allowed_tags Allowed HTML tags. Default empty string (strip all tags).
4027+ */
4028+ $ excerpt_allowed_tags = apply_filters ( 'excerpt_allowed_tags ' , '' );
4029+
4030+ if ( '' !== $ excerpt_allowed_tags ) {
4031+ $ text_to_trim = strip_tags ( $ text , $ excerpt_allowed_tags );
4032+
4033+ $ plain_text = wp_strip_all_tags ( $ text_to_trim );
4034+
4035+ if ( str_starts_with ( wp_get_word_count_type (), 'characters ' ) && preg_match ( '/^utf\-?8$/i ' , get_option ( 'blog_charset ' ) ) ) {
4036+ $ plain_text = trim ( preg_replace ( "/[ \n\r\t ]+/ " , ' ' , $ plain_text ), ' ' );
4037+ preg_match_all ( '/./u ' , $ plain_text , $ chars );
4038+ $ needs_trim = count ( $ chars [0 ] ) > $ excerpt_length ;
4039+
4040+ if ( $ needs_trim ) {
4041+ $ char_count = 0 ;
4042+ $ cut_pos = strlen ( $ text_to_trim );
4043+ $ remaining = $ text_to_trim ;
4044+ $ offset = 0 ;
4045+
4046+ while ( '' !== $ remaining ) {
4047+ if ( '< ' === $ remaining [0 ] ) {
4048+ $ tag_end = strpos ( $ remaining , '> ' );
4049+ if ( false === $ tag_end ) {
4050+ break ;
4051+ }
4052+ $ offset += $ tag_end + 1 ;
4053+ $ remaining = substr ( $ remaining , $ tag_end + 1 );
4054+ continue ;
4055+ }
4056+
4057+ if ( preg_match ( '/^./us ' , $ remaining , $ m ) ) {
4058+ ++$ char_count ;
4059+ if ( $ char_count > $ excerpt_length ) {
4060+ $ cut_pos = $ offset ;
4061+ break ;
4062+ }
4063+ $ offset += strlen ( $ m [0 ] );
4064+ $ remaining = substr ( $ remaining , strlen ( $ m [0 ] ) );
4065+ } else {
4066+ break ;
4067+ }
4068+ }
4069+
4070+ $ text = force_balance_tags ( substr ( $ text_to_trim , 0 , $ cut_pos ) ) . $ excerpt_more ;
4071+ } else {
4072+ $ text = $ text_to_trim ;
4073+ }
4074+ } else {
4075+ $ words = preg_split ( "/[ \n\r\t ]+/ " , $ plain_text , $ excerpt_length + 1 , PREG_SPLIT_NO_EMPTY );
4076+
4077+ if ( count ( $ words ) > $ excerpt_length ) {
4078+ $ word_count = 0 ;
4079+ $ cut_pos = strlen ( $ text_to_trim );
4080+ $ remaining = $ text_to_trim ;
4081+ $ offset = 0 ;
4082+
4083+ while ( '' !== $ remaining ) {
4084+ if ( '< ' === $ remaining [0 ] ) {
4085+ $ tag_end = strpos ( $ remaining , '> ' );
4086+ if ( false === $ tag_end ) {
4087+ break ;
4088+ }
4089+ $ offset += $ tag_end + 1 ;
4090+ $ remaining = substr ( $ remaining , $ tag_end + 1 );
4091+ continue ;
4092+ }
4093+
4094+ if ( preg_match ( '/^(\S+)/ ' , $ remaining , $ m ) ) {
4095+ ++$ word_count ;
4096+ if ( $ word_count > $ excerpt_length ) {
4097+ $ cut_pos = $ offset ;
4098+ break ;
4099+ }
4100+ $ offset += strlen ( $ m [0 ] );
4101+ $ remaining = substr ( $ remaining , strlen ( $ m [0 ] ) );
4102+ } elseif ( preg_match ( '/^(\s+)/ ' , $ remaining , $ m ) ) {
4103+ $ offset += strlen ( $ m [0 ] );
4104+ $ remaining = substr ( $ remaining , strlen ( $ m [0 ] ) );
4105+ } else {
4106+ break ;
4107+ }
4108+ }
4109+
4110+ $ text = force_balance_tags ( substr ( $ text_to_trim , 0 , $ cut_pos ) ) . $ excerpt_more ;
4111+ } else {
4112+ $ text = $ text_to_trim ;
4113+ }
4114+ }
4115+ } else {
4116+ $ text = wp_trim_words ( $ text , $ excerpt_length , $ excerpt_more );
4117+ }
40214118
40224119 }
40234120
0 commit comments