Repository: getpelican/pelican

Issue:
SUMMARY_MAX_LENGTH is applied in a wrong way to Vietnamese content
<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this, let’s make sure of a few things.
  Please make sure the following boxes are ticked if they are correct.
  If not, please try and fulfill them first.
-->

<!-- Checked checkbox should look like this: [x] -->
- [x] I have read the [Filing Issues](https://docs.getpelican.com/en/latest/contribute.html#filing-issues) and subsequent “How to Get Help” sections of the documentation.
- [x] I have searched the [issues](https://github.com/getpelican/pelican/issues?q=is%3Aissue) (including closed ones) and believe that this is not a duplicate.

<!--
  Once the above boxes are checked, if you are able to fill in the following list
  with your information, it would be very helpful for maintainers.
-->

- **OS version and name**: Ubuntu 21.10
- **Python version**: 3.10.2
- **Pelican version**: 4.7.2
- **Link to theme**: N/A, I use my self-made theme
- **Links to plugins**: None
- **Link to your site**: https://manhhomienbienthuy.github.io/
- **Link to your source**: It‘s not published.
- **Link to a [Gist](https://gist.github.com/) with the contents of your settings file**: <!-- If your source is not accessible, put Gist link here --> https://gist.github.com/manhhomienbienthuy/b989f84c7551d9ff13549e260cfb9450

## Issue
<!--
  Now feel free to write your issue. Please avoid vague phrases like “[…] doesn’t work”.
  Be descriptive! Thanks again 🙌 ❤️
-->

When a site contains articles in Vietnamese, the summary on index page generated by pelican will be much shorter than SUMMARY_MAX_LENGTH. I use default setting for SUMMARY_MAX_LENGTH = 50, but it's obviously less than 50 words (only about 35-36 words). But the biggest problem is that, sometimes the last word is broken in the middle and only some first characters remaining. I copied generated results here, so that you can have a direct compare:

```
Bài toán FizzBuzz thì quá kinh điển rồi, có lẽ ai học lập trình cũng đã từng làm quen với bài toán này ít nhất một lần. Trong bài viết này, tôi sẽ tổng hợp một s […] 
```

When I used version 4.6.0, it had no problems. Here is the result

```
Bài toán FizzBuzz thì quá kinh điển rồi, có lẽ ai học lập trình cũng đã từng làm quen với bài toán này ít nhất một lần. Trong bài viết này, tôi sẽ tổng hợp một số các khác nhau để giải bài toán này với ngôn ngữ Python. Mục […] 
```


Discussion:

Resolving patch:
diff --git a/pelican/utils.py b/pelican/utils.py
--- a/pelican/utils.py
+++ b/pelican/utils.py
@@ -412,10 +412,7 @@ def posixize_path(rel_path):
 
 class _HTMLWordTruncator(HTMLParser):
 
-    _word_regex = re.compile(r"(({SBC})({SBC}|-|')*)|{DBC}".format(
-        # SBC means Latin-like characters. A word contains a few characters.
-        #         ASCII |Extended Latin | Cyrillic
-        SBC="[0-9a-zA-Z]|[\u00C0-\u024f]|[\u0400-\u04FF]",
+    _word_regex = re.compile(r"{DBC}|(\w[\w'-]*)".format(
         # DBC means CJK-like characters. An character can stand for a word.
         DBC=("([\u4E00-\u9FFF])|"          # CJK Unified Ideographs
              "([\u3400-\u4DBF])|"          # CJK Unified Ideographs Extension A


Test patch:
diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py
--- a/pelican/tests/test_utils.py
+++ b/pelican/tests/test_utils.py
@@ -230,6 +230,11 @@ def test_truncate_html_words(self):
                 'Ты мелькнула, ты предстала, Снова сердце задрожало,', 3
             ),
             'Ты мелькнула, ты' + ' …')
+        self.assertEqual(
+            utils.truncate_html_words(
+                'Trong đầm gì đẹp bằng sen', 4
+            ),
+            'Trong đầm gì đẹp' + ' …')
 
         # Words enclosed or intervaled by HTML tags.
         self.assertEqual(