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 {
return content
}
if maxLen > len(content) {
maxLen = len(content)
}
return content[:maxLen] + "..."
}

View File

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

View File

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