9fd718b2ae
The composite renderer bypassed the pager (less) for any email with images, losing colors, scrolling, and search. Now always forward to the pager with [image: alt] text placeholders. Image refs are still extracted and stored for future inline rendering.
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
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
|
|
}
|
|
|
|
// ReplacePlaceholders converts \x00IMG:N\x00 placeholders into human-readable
|
|
// [image: alt] text suitable for display in a pager.
|
|
func ReplacePlaceholders(data []byte, images []ImageRef) []byte {
|
|
result := bytes.NewBuffer(nil)
|
|
for _, line := range bytes.Split(data, []byte("\n")) {
|
|
trimmed := bytes.TrimSpace(line)
|
|
if len(trimmed) > 6 && trimmed[0] == 0 &&
|
|
bytes.HasPrefix(trimmed, []byte("\x00IMG:")) &&
|
|
trimmed[len(trimmed)-1] == 0 {
|
|
// Extract index
|
|
numStr := string(trimmed[5 : len(trimmed)-1])
|
|
idx := 0
|
|
for _, c := range numStr {
|
|
if c >= '0' && c <= '9' {
|
|
idx = idx*10 + int(c-'0')
|
|
}
|
|
}
|
|
if idx < len(images) && images[idx].Alt != "" {
|
|
fmt.Fprintf(result, "[image: %s]\n", images[idx].Alt)
|
|
} else {
|
|
result.WriteString("[image]\n")
|
|
}
|
|
} else {
|
|
result.Write(line)
|
|
result.WriteByte('\n')
|
|
}
|
|
}
|
|
return result.Bytes()
|
|
}
|