package vault import ( "bytes" "regexp" "strings" ) // RewriteAssetLinks 在笔记改名后,把正文中指向旧图片目录(oldBase.assets/)的链接改为新目录。 // 覆盖行内链接/图片 `](…)`、引用定义 `[x]: …` 与 HTML `src="…"`,跳过围栏代码块和行内代码。 func RewriteAssetLinks(content []byte, oldBase, newBase string) []byte { oldRaw := regexp.QuoteMeta(oldBase + AssetsExt + "/") oldEsc := regexp.QuoteMeta(EscapeLinkPath(oldBase+AssetsExt) + "/") target := `(\./)?(?:` + oldRaw + `|` + oldEsc + `)` inline := regexp.MustCompile(`(\]\(\s* 3 { return nil } rest := line[indent:] if len(rest) < 3 || (rest[0] != '`' && rest[0] != '~') { return nil } n := 0 for n < len(rest) && rest[n] == rest[0] { n++ } if n < 3 || (rest[0] == '`' && bytes.IndexByte(rest[n:], '`') >= 0) { return nil } return rest[:n] } // replaceOutsideCode 只在行内代码 `…` 之外的片段上做替换 func replaceOutsideCode(line []byte, re *regexp.Regexp, repl []byte) []byte { var out []byte for len(line) > 0 { start := bytes.IndexByte(line, '`') if start < 0 { break } n := 1 for start+n < len(line) && line[start+n] == '`' { n++ } end := bytes.Index(line[start+n:], line[start:start+n]) if end < 0 { break } codeEnd := start + n + end + n out = append(out, re.ReplaceAll(line[:start], repl)...) out = append(out, line[start:codeEnd]...) line = line[codeEnd:] } return append(out, re.ReplaceAll(line, repl)...) }