diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 6f446a0e29b..3139fd8e23d 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -8375,10 +8375,27 @@ function moodle_setlocale($locale='') { * Words are defined as things between whitespace. * * @category string - * @param string $string The text to be searched for words. + * @param string $string The text to be searched for words. May be HTML. * @return int The count of words in the specified string */ function count_words($string) { + // Before stripping tags, add a space after the close tag of anything that is not obviously inline. + // Also, br is a special case because it definitely delimits a word, but has no close tag. + $string = preg_replace('~ + ( # Capture the tag we match. + | b> | del> | em> | i> | + ins> | s> | small> | + strong> | sub> | sup> | u> + ) + \w+ # But, apart from those execptions, match any tag name. + > # End of close tag. + | +
| # Special cases that are not close tags. + ) + ~x', '$1 ', $string); // Add a space after the close tag. + // Now remove HTML tags. $string = strip_tags($string); // Decode HTML entities. $string = html_entity_decode($string); diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 8c02d58b1b8..d3733c768a2 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -3792,7 +3792,7 @@ class core_moodlelib_testcase extends advanced_testcase { } /** - * Test function count_words(). + * Test function {@see count_words()}. * * @dataProvider count_words_testcases * @param int $expectedcount number of words in $string. @@ -3809,16 +3809,30 @@ class core_moodlelib_testcase extends advanced_testcase { */ public function count_words_testcases(): array { return [ + [0, ''], + [4, 'one two three four'], [3, "one two three'four"], [3, 'one+two three’four'], [2, 'one"two three-four'], [4, 'one@two three_four'], [4, 'one\two three/four'], + [4, '

one two

three four

'], + [4, '

one two
three four

'], + [4, '

one two
three four

'], // XHTML style. [4, ' one ... two   three...four '], [4, 'one.2 3,four'], [4, '1³ £2 €3.45 $6,789'], [4, 'one—two ブルース カンベッル'], [4, 'one…two ブルース … カンベッル'], + [4, '

one two

three four

'], + [4, '

one two


three four

'], + [4, '

one

four.

'], + [1, '

emphasis.

'], + [1, '

emphasis.

'], + [1, '

emphasis.

'], + [1, '

emphasis.

'], + [2, "one\ntwo"], + [1, "SO42-"], ]; }