1
0
mirror of https://github.com/ialley-workshop-open/uni-halo.git synced 2026-09-12 16:40:40 +08:00
Files
uni-halo/src/utils/text.ts
T
小莫唐尼 62b604644c feat: 新增收藏功能与多项体验优化
- 新增本地收藏store与工具函数,支持文章/瞬间收藏持久化
- 重构插件可用性检查hook,统一管理依赖插件状态
- 替换旧数据加载hook为新的状态管理方案
- 优化首页布局与加载逻辑,调整公告组件样式
- 为瞬间详情页添加点赞、评论与收藏功能
- 新增文本处理工具,支持HTML/Markdown转纯文本与摘要截断
- 修复评论弹窗适配瞬间类型的参数问题
2026-09-04 17:17:18 +08:00

52 lines
1.7 KiB
TypeScript

/**
* 文本工具:HTML 剥离为纯文本 + 摘要截断
* 跨端实现(小程序无 DOM),仅用正则处理,不依赖 DOMParser
*/
/** HTML 实体解码(覆盖常见实体即可) */
const HTML_ENTITY_MAP: Record<string, string> = {
'&nbsp;': ' ',
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#39;': '\'',
'&amp;': '&',
}
/** 行首 markdown 标记(# 标题 / * - 列表 / 数字序号 / 引用 > / 代码块 ``` 等) */
const MD_PREFIX_REG = /^\s{0,3}(#{1,6}[ \t]|>|[+*-][ \t]|\d+[.、)][ \t]|```|~~~|!?\[)/gm
/**
* 将 HTML/Markdown 源文本剥离为压缩空白后的纯文本
* @param source 原文(可为空)
*/
export function htmlToPlainText(source?: string): string {
if (!source)
return ''
let text = source
// 剥离脚本/样式块
text = text.replace(/<(script|style)[\s\S]*?<\/\1>/gi, ' ')
// 块级/换行标签替换为空格,其余标签整体剥离
text = text
.replace(/<\/(p|div|br|li|h[1-6]|blockquote|pre|tr|section|article)>/gi, ' ')
.replace(/<[^>]+>/g, ' ')
// markdown 行首符号清理
text = text.replace(MD_PREFIX_REG, '')
// 实体解码
text = text.replace(/&[a-z]+;|&#\d+;/gi, match => HTML_ENTITY_MAP[match.toLowerCase()] ?? ' ')
// 压缩空白(含换行)
return text.replace(/\s+/g, ' ').trim()
}
/** 截断文本,超长追加省略号 */
export function truncateText(text: string, max: number, ellipsis = '…'): string {
if (!text || text.length <= max)
return text
return `${text.slice(0, max).trimEnd()}${ellipsis}`
}
/** 从 HTML/Markdown 源提取纯文本摘要(去标签 + 截断) */
export function extractPlainExcerpt(source?: string, max = 120): string {
return truncateText(htmlToPlainText(source), max)
}