ResolveLocalImagePaths scans HTML for references, validates each path, generates CIDs, and returns the modified HTML with cid: URIs plus the list of local image references to embed as inline parts. This function handles only the HTML transformation; callers are responsible for
(html string)
| 1027 | // This function handles only the HTML transformation; callers are responsible |
| 1028 | // for embedding the actual file data (e.g., via emlbuilder.AddFileInline). |
| 1029 | func ResolveLocalImagePaths(html string) (string, []LocalImageRef, error) { |
| 1030 | matches := imgSrcRegexp.FindAllStringSubmatchIndex(html, -1) |
| 1031 | if len(matches) == 0 { |
| 1032 | return html, nil, nil |
| 1033 | } |
| 1034 | |
| 1035 | // Cache resolved paths so the same file is only attached once. |
| 1036 | pathToCID := make(map[string]string) |
| 1037 | var refs []LocalImageRef |
| 1038 | |
| 1039 | // Iterate in reverse so that index offsets remain valid after replacement. |
| 1040 | for i := len(matches) - 1; i >= 0; i-- { |
| 1041 | srcStart, srcEnd := matches[i][2], matches[i][3] |
| 1042 | src := html[srcStart:srcEnd] |
| 1043 | if !isLocalFileSrc(src) { |
| 1044 | continue |
| 1045 | } |
| 1046 | |
| 1047 | resolvedPath, err := validate.SafeInputPath(src) |
| 1048 | if err != nil { |
| 1049 | return "", nil, fmt.Errorf("inline image %q: %w", src, err) |
| 1050 | } |
| 1051 | |
| 1052 | cid, ok := pathToCID[resolvedPath] |
| 1053 | if !ok { |
| 1054 | cid, err = generateCID() |
| 1055 | if err != nil { |
| 1056 | return "", nil, err |
| 1057 | } |
| 1058 | pathToCID[resolvedPath] = cid |
| 1059 | refs = append(refs, LocalImageRef{FilePath: src, CID: cid}) |
| 1060 | } |
| 1061 | |
| 1062 | html = html[:srcStart] + "cid:" + cid + html[srcEnd:] |
| 1063 | } |
| 1064 | |
| 1065 | return html, refs, nil |
| 1066 | } |
| 1067 | |
| 1068 | // resolveLocalImgSrc scans HTML for <img src="local/path"> references, |
| 1069 | // creates MIME inline parts for each local file, and returns the HTML |