Repository: zulip/zulip

Issue:
Add delimiter between paragraphs and bullets in open graph descriptions
Split from #12178 

> I think we might want to make consider making bulleted lists have some sort of delimeter between the bullets (see the Slack preview, which is long enough to run into this, above). Possibly just converting those back into * might be a good idea. Maybe new paragraph into |, and bullets into *?


Discussion:
@zulipbot claim
@rishig  @timabbott The text for czo would read something like this, with the `|` and `*` as delimiters. 

> Welcome to the Zulip development and user community! | Join to get a quick Zulip demo, observe a Zulip community, offer feedback to the Zulip core team, or get involved in as a contributor. * Community conventions * Code of Conduct | Note that this server runs a bleeding-edge version of Zulip, so you may encounter bugs. Please report them!

Does this seem ok to you?

Resolving patch:
diff --git a/zerver/lib/html_to_text.py b/zerver/lib/html_to_text.py
--- a/zerver/lib/html_to_text.py
+++ b/zerver/lib/html_to_text.py
@@ -1,4 +1,4 @@
-from typing import List, Optional
+from typing import Dict, Optional
 
 from bs4 import BeautifulSoup
 from django.http import HttpRequest
@@ -6,7 +6,7 @@
 
 from zerver.lib.cache import cache_with_key, open_graph_description_cache_key
 
-def html_to_text(content: str, tags: Optional[List[str]]=None) -> str:
+def html_to_text(content: str, tags: Optional[Dict[str, str]]=None) -> str:
     bs = BeautifulSoup(content, features='lxml')
     # Skip any admonition (warning) blocks, since they're
     # usually something about users needing to be an
@@ -21,10 +21,15 @@ def html_to_text(content: str, tags: Optional[List[str]]=None) -> str:
 
     text = ''
     if tags is None:
-        tags = ['p']
-    for paragraph in bs.find_all(tags):
+        tags = {'p': ' | '}
+    for element in bs.find_all(tags.keys()):
+        # Ignore empty elements
+        if not element.text:
+            continue
         # .text converts it from HTML to text
-        text = text + paragraph.text + ' '
+        if text:
+            text += tags[element.name]
+        text += element.text
         if len(text) > 500:
             break
     return escape(' '.join(text.split()))
diff --git a/zerver/lib/realm_description.py b/zerver/lib/realm_description.py
--- a/zerver/lib/realm_description.py
+++ b/zerver/lib/realm_description.py
@@ -13,4 +13,4 @@ def get_realm_rendered_description(realm: Realm) -> str:
 @cache_with_key(realm_text_description_cache_key, timeout=3600*24*7)
 def get_realm_text_description(realm: Realm) -> str:
     html_description = get_realm_rendered_description(realm)
-    return html_to_text(html_description, ['p', 'li'])
+    return html_to_text(html_description, {'p': ' | ', 'li': ' * '})


Test patch:
diff --git a/zerver/tests/test_middleware.py b/zerver/tests/test_middleware.py
--- a/zerver/tests/test_middleware.py
+++ b/zerver/tests/test_middleware.py
@@ -83,7 +83,7 @@ def test_admonition_and_link(self) -> None:
             '/help/disable-message-edit-history',
             "Disable message edit history (Zulip Help Center)",
             ["By default, Zulip displays messages",
-             "users can view the edit history of a message. To remove the",
+             "users can view the edit history of a message. | To remove the",
              "best to delete the message entirely. "],
             ["Disable message edit history", "feature is only available", "Related articles",
              "Restrict message editing"]
@@ -104,7 +104,7 @@ def test_settings_tab(self) -> None:
         self.check_title_and_description(
             '/help/deactivate-your-account',
             "Deactivate your account (Zulip Help Center)",
-            ["Any bots that you maintain will be disabled. Deactivating "],
+            ["Any bots that you maintain will be disabled. | Deactivating "],
             ["Confirm by clicking", "  ", "\n"])
 
     def test_tabs(self) -> None:
@@ -135,7 +135,7 @@ def test_nonexistent_page(self) -> None:
             '/help/not-a-real-page',
             # Probably we should make this "Zulip Help Center"
             "No such article. (Zulip Help Center)",
-            ["No such article. We're here to help!",
+            ["No such article. | We're here to help!",
              "Email us at zulip-admin@example.com with questions, feedback, or feature requests."],
             [],
             # Test that our open graph logic doesn't throw a 500
@@ -166,7 +166,7 @@ def test_login_page_markdown_description(self) -> None:
             '/login/',
             'Zulip Dev',
             ['Welcome to Clojurians Zulip - the place where the Clojure community meets',
-             'note-1', 'note-2', 'note-3', 'Enjoy!'],
+             '* note-1 * note-2 * note-3 | Enjoy!'],
             [])
 
     def test_login_page_realm_icon(self) -> None: