slug生成采用既有工具。
This commit is contained in:
@@ -8,6 +8,7 @@ require (
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
github.com/go-sql-driver/mysql v1.10.0
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/gosimple/slug v1.15.0
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/yuin/goldmark v1.8.5
|
||||
golang.org/x/crypto v0.53.0
|
||||
@@ -30,6 +31,7 @@ require (
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gosimple/unidecode v1.0.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
|
||||
@@ -50,6 +50,10 @@ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17k
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gosimple/slug v1.15.0 h1:wRZHsRrRcs6b0XnxMUBM6WK1U1Vg5B0R7VkIf1Xzobo=
|
||||
github.com/gosimple/slug v1.15.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=
|
||||
github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=
|
||||
github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"goblog/database"
|
||||
@@ -13,6 +12,7 @@ import (
|
||||
"goblog/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gosimple/slug"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -69,10 +69,7 @@ func PreviewMarkdown(c *gin.Context) {
|
||||
|
||||
// 生成 slug
|
||||
func generateSlug(title string) string {
|
||||
slug := strings.ToLower(title)
|
||||
slug = strings.ReplaceAll(slug, " ", "-")
|
||||
slug = strings.ReplaceAll(slug, "_", "-")
|
||||
// 简化处理,实际项目中可能需要更完善的 slug 生成
|
||||
slug := slug.Make(title)
|
||||
return slug
|
||||
}
|
||||
|
||||
|
||||
+56
-39
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user