Skip to content

Commit 47623bb

Browse files
committed
fix: Fix Text Orphan update to match text inside of HTML tags. Fixes #374.
1 parent 21862d9 commit 47623bb

File tree

1 file changed

+31
-16
lines changed

1 file changed

+31
-16
lines changed

inc/lib/helpers.php

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,28 +156,43 @@ function get_complete_meta($post_id, $meta_key)
156156

157157

158158
/**
159-
* Fix text orphan
160-
*
161-
* Make last space in a sentence a non breaking space to prevent typographic widows.
162-
*
159+
* Fix text orphans by adding a non-breaking space before the last word,
160+
* while ignoring HTML tags such as <a>, <strong>, etc.
161+
*
163162
* @since 3.2.0
164-
* @param type $str
165-
* @param type $min_word_count
166-
* @return string
163+
* @param string $str The input string which may contain HTML.
164+
* @param int $min_word_count The minimum word count required to apply the fix.
165+
* @return string The processed string with a non-breaking space before the last word in plain text.
167166
*/
168167
function fix_text_orphan($str = '', $min_word_count = 3)
169168
{
170-
$str = trim($str); // Strip spaces.
171-
$space = strrpos($str, ' '); // Find the last space.
172-
$word_count = str_word_count($str);
169+
// Trim the input string to remove excess spaces.
170+
$str = trim($str);
173171

174-
// If there's a space then replace the last on with a non breaking space.
175-
if ((false !== $space) && $word_count > $min_word_count) {
176-
$str = substr($str, 0, $space) . '&nbsp;' . substr($str, $space + 1);
177-
}
172+
// Regex to match all words, ignoring anything inside HTML tags
173+
$pattern = '/>([^<]+)</'; // Matches the text between HTML tags
174+
175+
// Callback function to apply the non-breaking space logic to text content
176+
$str = preg_replace_callback($pattern, function ($matches) use ($min_word_count) {
177+
// Get the text between HTML tags
178+
$text = $matches[1];
179+
180+
// Find the last space
181+
$space = strrpos($text, ' ');
182+
183+
// Count words in the text
184+
$word_count = str_word_count($text);
185+
186+
// Apply the non-breaking space if word count is above the threshold and a space exists
187+
if ($space !== false && $word_count > $min_word_count) {
188+
$text = substr($text, 0, $space) . '&nbsp;' . substr($text, $space + 1);
189+
}
190+
191+
// Return the processed text between the original HTML tags
192+
return '>' . $text . '<';
193+
}, $str);
178194

179-
// Return the string.
180-
return $str;
195+
return $str;
181196
}
182197

183198

0 commit comments

Comments
 (0)