b3bbd55551
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>
63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
package parse
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
)
|
|
|
|
// ImageRef represents an image referenced by a filter via OSC 9 marker.
|
|
type ImageRef struct {
|
|
Index int // Sequential position in the message; set by ExtractImages, not ParseImageOSC
|
|
Path string // Absolute path to image file on disk
|
|
Alt string // Alt text fallback
|
|
}
|
|
|
|
var oscImagePrefix = []byte("\033]9;image:")
|
|
|
|
// ParseImageOSC parses an OSC 9 image marker from a byte slice.
|
|
// Format: \033]9;image:path=/tmp/foo.png;alt=text\007
|
|
// The marker may appear anywhere in the line.
|
|
// Returns the parsed reference and whether parsing succeeded.
|
|
func ParseImageOSC(line []byte) (*ImageRef, bool) {
|
|
start := bytes.Index(line, oscImagePrefix)
|
|
if start == -1 {
|
|
return nil, false
|
|
}
|
|
rest := line[start+len(oscImagePrefix):]
|
|
|
|
// Find string terminator: BEL (\007) or ST (ESC \)
|
|
end := -1
|
|
for i := 0; i < len(rest); i++ {
|
|
if rest[i] == '\007' {
|
|
end = i
|
|
break
|
|
}
|
|
if rest[i] == '\033' && i+1 < len(rest) && rest[i+1] == '\\' {
|
|
end = i
|
|
break
|
|
}
|
|
}
|
|
if end == -1 {
|
|
return nil, false
|
|
}
|
|
|
|
params := string(rest[:end])
|
|
ref := &ImageRef{}
|
|
for _, pair := range strings.Split(params, ";") {
|
|
k, v, ok := strings.Cut(pair, "=")
|
|
if !ok {
|
|
continue
|
|
}
|
|
switch k {
|
|
case "path":
|
|
ref.Path = v
|
|
case "alt":
|
|
ref.Alt = v
|
|
}
|
|
}
|
|
if ref.Path == "" {
|
|
return nil, false
|
|
}
|
|
return ref, true
|
|
}
|