This commit is contained in:
Mrx
2026-03-16 13:10:42 +08:00
parent 14b2c53eeb
commit 6f0a8e0519
3 changed files with 35 additions and 16 deletions

View File

@@ -552,6 +552,9 @@ func (r *DatabaseTableReader) getContentPreview(content string, maxLen int) stri
if len(content) <= maxLen { if len(content) <= maxLen {
return content return content
} }
if maxLen > len(content) {
maxLen = len(content)
}
return content[:maxLen] + "..." return content[:maxLen] + "..."
} }

View File

@@ -1186,10 +1186,14 @@ func (pb *PageBuilder) drawRichTextBlock(pdf *gofpdf.Fpdf, text string, contentW
// getContentPreview 获取内容预览(用于日志记录) // getContentPreview 获取内容预览(用于日志记录)
func (pb *PageBuilder) getContentPreview(content string, maxLen int) string { func (pb *PageBuilder) getContentPreview(content string, maxLen int) string {
content = strings.TrimSpace(content) content = strings.TrimSpace(content)
if len(content) <= maxLen { if maxLen <= 0 || len(content) <= maxLen {
return content return content
} }
return content[:maxLen] + "..." n := maxLen
if n > len(content) {
n = len(content)
}
return content[:n] + "..."
} }
// wrapJSONLinesToWidth 将 JSON 文本按宽度换行,返回用于绘制的行列表(兼容中文等) // wrapJSONLinesToWidth 将 JSON 文本按宽度换行,返回用于绘制的行列表(兼容中文等)

View File

@@ -175,10 +175,11 @@ func (tp *TextProcessor) parseInlineSegments(block string) []inlineSeg {
if plain == "" { if plain == "" {
return segs return segs
} }
// 在原始 block 上找加粗区间,再映射到 plain去掉标签后的位置 // 在 block 上找加粗区间,再映射到 plain去掉标签后的位置
// 注意work 每次循环被截断,必须用相对 work 的索引切片,避免 work[:endInWork] 越界
work := block work := block
var boldRanges [][2]int var boldRanges [][2]int
offset := 0 plainOffset := 0
for { for {
idxOpen := reBoldOpen.FindStringIndex(work) idxOpen := reBoldOpen.FindStringIndex(work)
if idxOpen == nil { if idxOpen == nil {
@@ -189,34 +190,45 @@ func (tp *TextProcessor) parseInlineSegments(block string) []inlineSeg {
if idxClose == nil { if idxClose == nil {
break break
} }
startInWork := offset + idxOpen[1] closeLen := len(reBoldClose.FindString(afterOpen))
endInWork := offset + idxOpen[1] + idxClose[0] // 使用相对当前 work 的字节偏移,保证 work[:endInWork] 不越界
// 将 work 坐标映射到 plain需要数 plain 中对应字符 endInWork := idxOpen[1] + idxClose[0]
workBefore := work[:startInWork] workBefore := work[:idxOpen[1]]
plainBefore := regexp.MustCompile(`<[^>]+>`).ReplaceAllString(workBefore, "") plainBefore := regexp.MustCompile(`<[^>]+>`).ReplaceAllString(workBefore, "")
plainBefore = regexp.MustCompile(`[ \t]+`).ReplaceAllString(plainBefore, " ") plainBefore = regexp.MustCompile(`[ \t]+`).ReplaceAllString(plainBefore, " ")
startPlain := len([]rune(plainBefore)) startPlain := plainOffset + len([]rune(plainBefore))
workUntil := work[:endInWork] workUntil := work[:endInWork]
plainUntil := regexp.MustCompile(`<[^>]+>`).ReplaceAllString(workUntil, "") plainUntil := regexp.MustCompile(`<[^>]+>`).ReplaceAllString(workUntil, "")
plainUntil = regexp.MustCompile(`[ \t]+`).ReplaceAllString(plainUntil, " ") plainUntil = regexp.MustCompile(`[ \t]+`).ReplaceAllString(plainUntil, " ")
endPlain := len([]rune(plainUntil)) endPlain := plainOffset + len([]rune(plainUntil))
boldRanges = append(boldRanges, [2]int{startPlain, endPlain}) boldRanges = append(boldRanges, [2]int{startPlain, endPlain})
work = work[endInWork+len(reBoldClose.FindString(afterOpen)):] consumed := work[:endInWork+closeLen]
offset = endInWork + len(reBoldClose.FindString(afterOpen)) strippedConsumed := regexp.MustCompile(`<[^>]+>`).ReplaceAllString(consumed, "")
strippedConsumed = regexp.MustCompile(`[ \t]+`).ReplaceAllString(strippedConsumed, " ")
plainOffset += len([]rune(strippedConsumed))
work = work[endInWork+closeLen:]
} }
// 按 boldRanges 切分 plain // 按 boldRanges 切分 plain(限制区间在 [0,len(runes)] 内,防止越界)
runes := []rune(plain) runes := []rune(plain)
nr := len(runes)
inBold := false inBold := false
var start int var start int
for i := 0; i <= len(runes); i++ { for i := 0; i <= nr; i++ {
nowBold := false nowBold := false
for _, r := range boldRanges { for _, r := range boldRanges {
if i >= r[0] && i < r[1] { r0, r1 := r[0], r[1]
if r0 < 0 {
r0 = 0
}
if r1 > nr {
r1 = nr
}
if r0 < r1 && i >= r0 && i < r1 {
nowBold = true nowBold = true
break break
} }
} }
if nowBold != inBold || i == len(runes) { if nowBold != inBold || i == nr {
if i > start { if i > start {
segs = append(segs, inlineSeg{Text: string(runes[start:i]), Bold: inBold}) segs = append(segs, inlineSeg{Text: string(runes[start:i]), Bold: inBold})
} }