slug生成采用既有工具。

This commit is contained in:
2026-08-31 17:50:58 +08:00
parent f216ef4d1b
commit 2bcfa1da93
4 changed files with 64 additions and 44 deletions
+56 -39
View File
@@ -34,83 +34,100 @@ func RenderMarkdown(source string) template.HTML {
// 全局预编译正则(保持不变,但移除冗余)
var (
// 标题
// 块级语法
reHeading = regexp.MustCompile(`(?m)^\s*#{1,6}\s+`)
// 无序列表
// 列表
reUnorderedList = regexp.MustCompile(`(?m)^\s*[-*+]\s+`)
// 有序列表
reOrderedList = regexp.MustCompile(`(?m)^\s*\d+[.)]\s+`)
// 块引用
reBlockquote = regexp.MustCompile(`(?m)^\s*>\s+`)
// 水平线
// 分割线
reHr = regexp.MustCompile(`(?m)^\s*[-*_]{3,}\s*$`)
// 脚注定义
reFootnoteDef = regexp.MustCompile(`(?m)^\[\^.+?\]:\s.*$`)
// 引用定义
reRefDef = regexp.MustCompile(`(?m)^\s*\[.+?\]:\s*(.*)$`)
// 图片
reImage = regexp.MustCompile(`(?s)!\[.*?\]\(.*?\)`)
// 引用图片
reFootnoteDef = regexp.MustCompile(`(?m)^\[\^.+?\]:\s.*$`)
reRefDef = regexp.MustCompile(`(?m)^\s*\[.+?\]:\s*(.*)$`)
// 图片(全部移除)
reImage = regexp.MustCompile(`!\[.*?\]\(.*?\)`)
reRefImage = regexp.MustCompile(`!\[.*?\](\[.*?\])?`)
// 链接
reLink = regexp.MustCompile(`(?s)\[(.*?)\]\(.*?\)`)
// 引用式链接
reRefLink = regexp.MustCompile(`\[([^\s=\[\]/]+)\](\[.*?\])?`)
// 粗体
reBoldStar = regexp.MustCompile(`(?s)\*\*(.*?)\*\*`)
// 斜体
reItalicStar = regexp.MustCompile(`(?s)\*(.*?)\*`)
// 下划线粗体
reBoldUnderscore = regexp.MustCompile(`(?s)_(.*?)_`)
// 下划线斜体
reItalicUnderscore = regexp.MustCompile(`(?s)_(.*?)_`)
// 内联链接 [text](url) → 保留 text
reLink = regexp.MustCompile(`\[([^\]]*)\]\([^)]*\)`)
// 引用式链接 [text][id] 或 [text][] → 保留 text
reRefLink = regexp.MustCompile(`\[([^\]]*)\](\[[^\]]*\])?`)
// 行内标记(加粗、斜体、删除线)
reBoldStar = regexp.MustCompile(`\*\*(.+?)\*\*`)
reBoldUnd = regexp.MustCompile(`__(.+?)__`)
reItalicStar = regexp.MustCompile(`\*(.+?)\*`) // 注意:必须在粗体之后处理
reItalicUnd = regexp.MustCompile(`_(.+?)_`) // 同上
reStrike = regexp.MustCompile(`~~(.+?)~~`) // 删除线
// 为保留代码内容(可能含关键词),此处只移除反引号,但代码块可能多行,我们保留内容。
reCodeInline = regexp.MustCompile("`([^`]*)`")
reCodeBlock = regexp.MustCompile("(?s)```(.*?)```")
// HTML 标签
reHTMLTag = regexp.MustCompile(`<[^>]+>`)
// 表格分隔线(移除 --- 行,保留内容)
reTableSep = regexp.MustCompile(`(?m)^\s*\|?\s*[-:]+[-| :]+\s*\|?\s*$`)
// 多余空白
reMultiSpace = regexp.MustCompile(`\s+`)
)
// GenerateSearchableText 提取 Markdown 中的纯文本
// GenerateSearchableText 提取 Markdown 中的可见纯文本
func GenerateSearchableText(raw string) string {
if raw == "" {
return ""
}
text := raw
// 全角空格转半角
// 1. 全角空格转半角
text = strings.ReplaceAll(text, "\u3000", " ")
// 移除块级标记(一次性替换多个)
text = reHr.ReplaceAllString(text, "")
text = reBlockquote.ReplaceAllString(text, "")
// 2. 移除块级标记(标题、列表、引用、分割线)
text = reHeading.ReplaceAllString(text, "")
text = reUnorderedList.ReplaceAllString(text, "")
text = reOrderedList.ReplaceAllString(text, "")
text = reHeading.ReplaceAllString(text, "")
text = reBlockquote.ReplaceAllString(text, "")
text = reHr.ReplaceAllString(text, "")
// 移除引用定义
// 3. 移除引用定义行
text = reFootnoteDef.ReplaceAllString(text, "")
text = reRefDef.ReplaceAllString(text, "")
// 移除图片
// 4. 移除图片(所有形式)
text = reImage.ReplaceAllString(text, "")
text = reRefImage.ReplaceAllString(text, "")
// 处理链接:保留可见文字(先引用式后内联)
text = reRefLink.ReplaceAllString(text, "$1")
// 5. 移除代码块(整块移除,因为代码块内容通常不参与自然语言搜索)
text = reCodeBlock.ReplaceAllString(text, "$1")
// 6. 处理链接(先引用式后内联)
text = reLink.ReplaceAllString(text, "$1")
text = reRefLink.ReplaceAllString(text, "$1")
// 移除粗体
text = reBoldStar.ReplaceAllString(text, "")
text = reBoldUnderscore.ReplaceAllString(text, "")
// 移除斜体
text = reItalicStar.ReplaceAllString(text, "")
text = reItalicUnderscore.ReplaceAllString(text, "")
// 7. 移除行内代码反引号(保留代码内容)
text = reCodeInline.ReplaceAllString(text, "")
// 移除 HTML 标签
// 8. 移除粗体、斜体、删除线标记(保留文字)
text = reBoldStar.ReplaceAllString(text, "$1")
text = reBoldUnd.ReplaceAllString(text, "$1")
text = reItalicStar.ReplaceAllString(text, "$1")
text = reItalicUnd.ReplaceAllString(text, "$1")
text = reStrike.ReplaceAllString(text, "$1")
// 9. 移除表格分隔线(保留表格内容)
text = reTableSep.ReplaceAllString(text, "")
// 10. 移除 HTML 标签
text = reHTMLTag.ReplaceAllString(text, "")
// 压缩空白
// 11. 压缩空白
text = reMultiSpace.ReplaceAllString(text, " ")
return strings.TrimSpace(text)
}