|
|
@@ -195,6 +195,25 @@ def suppress_markdown_url_previews(markdown: str) -> str:
|
|
195
|
195
|
"""Finds URLs in markdown and encloses them in <...> to suppress the preview."""
|
|
196
|
196
|
return re.sub(r'(?<!<)(https?://\S+)(?!>)', '<\\1>', markdown)
|
|
197
|
197
|
|
|
|
198
|
+def truncate_markdown(markdown: str, max_length: int) -> str:
|
|
|
199
|
+ """Truncates markdown in a way that attempts to minimize formatting disruption."""
|
|
|
200
|
+ if len(markdown) <= max_length:
|
|
|
201
|
+ return markdown
|
|
|
202
|
+ markdown = markdown[:max_length]
|
|
|
203
|
+
|
|
|
204
|
+ # Try to cut at a newline if it's in the latter 20% of the max length
|
|
|
205
|
+ last_newline_index = markdown.rfind('\n')
|
|
|
206
|
+ if last_newline_index >= 0 and last_newline_index < (max_length * 8 / 10):
|
|
|
207
|
+ return markdown[:last_newline_index] + "\n\u2026"
|
|
|
208
|
+
|
|
|
209
|
+ # Cut at the last space
|
|
|
210
|
+ last_space_index = markdown.rfind(' ')
|
|
|
211
|
+ if last_space_index >= 0:
|
|
|
212
|
+ return markdown[:last_space_index] + " \u2026"
|
|
|
213
|
+
|
|
|
214
|
+ # Last resort, do a blind substring
|
|
|
215
|
+ return markdown[:max_length - 1] + "\u2026"
|
|
|
216
|
+
|
|
198
|
217
|
def format_bytes(size: int) -> str:
|
|
199
|
218
|
"""Formats s size in bytes to a human readable description (e.g. "3.2 KiB")"""
|
|
200
|
219
|
size = max(size, 0)
|