feat(parse): add ExtractImages stream scanner for OSC 9 markers

Implements ExtractImages() which scans filter stdout line-by-line,
extracts valid OSC 9 image markers into ImageRef structs, and replaces
marker lines with null-delimited placeholders (\x00IMG:N\x00). Invalid
markers (missing path) pass through unchanged. Also clarifies the Index
field comment in ImageRef to indicate it is set by ExtractImages, not
ParseImageOSC.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mortdecai
2026-04-07 20:01:10 -04:00
parent 00a6660db5
commit b3bbd55551
3 changed files with 143 additions and 1 deletions
+41
View File
@@ -0,0 +1,41 @@
package parse
import (
"bufio"
"bytes"
"fmt"
"io"
"git.sr.ht/~rjarry/aerc/lib/log"
)
// ExtractImages scans a reader for OSC 9 image markers, replaces them with
// null-byte-delimited placeholders (\x00IMG:N\x00), and returns the cleaned
// reader plus a slice of ImageRef structs.
//
// Lines containing valid image markers are replaced entirely with the
// placeholder. Lines with invalid markers (e.g. missing path) pass through
// unchanged.
func ExtractImages(r io.Reader) (io.Reader, []ImageRef) {
var images []ImageRef
buf := bytes.NewBuffer(nil)
scanner := bufio.NewScanner(r)
scanner.Buffer(nil, 1024*1024*1024)
for scanner.Scan() {
line := scanner.Bytes()
if bytes.Contains(line, oscImagePrefix) {
if ref, ok := ParseImageOSC(line); ok {
ref.Index = len(images)
images = append(images, *ref)
fmt.Fprintf(buf, "\x00IMG:%d\x00\n", ref.Index)
continue
}
}
buf.Write(line)
buf.WriteByte('\n')
}
if err := scanner.Err(); err != nil {
log.Warnf("ExtractImages: scan error: %v", err)
}
return buf, images
}