aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2026-06-10 18:23:04 -0700
committerRose Hogenson <rosehogenson@posteo.net>2026-06-10 18:23:04 -0700
commitadef688e11cabba97fb08909399b41992a78076c (patch)
tree430781adaf80d2b8783567d7b125feb9e3593768
parentc802e3c51a9ff2e4b398eabf64b3cb7a13264fad (diff)
downloadimgutil-adef688e11cabba97fb08909399b41992a78076c.tar.zst
Escape non-printing characters
-rw-r--r--ils.go22
1 files changed, 16 insertions, 6 deletions
diff --git a/ils.go b/ils.go
index e40c6f7..c18e07d 100644
--- a/ils.go
+++ b/ils.go
@@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"slices"
+ "strconv"
runewidth "github.com/mattn/go-runewidth"
_ "golang.org/x/image/bmp"
@@ -125,6 +126,15 @@ func printImg(w io.Writer, img image.Image) {
}
}
+func escapeString(s string) string {
+ for _, r := range s {
+ if !strconv.IsGraphic(r) {
+ return strconv.QuoteToGraphic(s)
+ }
+ }
+ return s
+}
+
func divRound(n, d int) int {
return (n + d/2) / d
}
@@ -139,7 +149,7 @@ func compositeImageRow(imagePaths []string, width, rowWidth, cellX int, aspectRa
if i > 0 {
logicalWidth += 2 * cellX
}
- fileNameWidth := cellX * runewidth.StringWidth(filepath.Base(filename))
+ fileNameWidth := cellX * runewidth.StringWidth(escapeString(filepath.Base(filename)))
logicalWidth += max(width, fileNameWidth)
imageWidth, imageHeight, err := imageDimensions(filename)
@@ -157,7 +167,7 @@ func compositeImageRow(imagePaths []string, width, rowWidth, cellX int, aspectRa
return nil, err
}
height := divRound(img.Bounds().Dy()*width*aspectRatio.x, img.Bounds().Dx()*aspectRatio.y)
- imageWidth := max(width, cellX*runewidth.StringWidth(filepath.Base(filename)))
+ imageWidth := max(width, cellX*runewidth.StringWidth(escapeString(filepath.Base(filename))))
start := divRound(offset*rowWidth, logicalWidth)
end := divRound((offset+imageWidth)*rowWidth, logicalWidth)
offsetStart := start + (end-start-width)/2
@@ -174,7 +184,7 @@ func splitRows(imagePaths []string, width, rowWidth int) [][]string {
row := imagePaths[:0]
thisRowWidth := 0
for ; len(row) < len(imagePaths); row = row[:len(row)+1] {
- nextW := max(width, runewidth.StringWidth(filepath.Base(imagePaths[len(row)])))
+ nextW := max(width, runewidth.StringWidth(escapeString(filepath.Base(imagePaths[len(row)]))))
if len(row) > 0 {
nextW += 2
}
@@ -232,7 +242,7 @@ func thumbnailFiles(w io.Writer, imagePaths []string, width, rowWidth, cellX, ce
if j > 0 {
thisRowWidth += 2
}
- thisRowWidth += max(width, runewidth.StringWidth(filepath.Base(filename)))
+ thisRowWidth += max(width, runewidth.StringWidth(escapeString(filepath.Base(filename))))
}
var rowImage image.Image
select {
@@ -251,11 +261,11 @@ func thumbnailFiles(w io.Writer, imagePaths []string, width, rowWidth, cellX, ce
start := divRound(offset*rowWidth, thisRowWidth)
fmt.Fprintf(w, "%*s", start-realOffset, "")
realOffset = start
- fileNameWidth := runewidth.StringWidth(filepath.Base(filename))
+ fileNameWidth := runewidth.StringWidth(escapeString(filepath.Base(filename)))
offset += max(width, fileNameWidth)
end := divRound(offset*rowWidth, thisRowWidth)
padding := (end - start - fileNameWidth) / 2
- fmt.Fprintf(w, "%*s%s", padding, "", filepath.Base(filename))
+ fmt.Fprintf(w, "%*s%s", padding, "", escapeString(filepath.Base(filename)))
realOffset += padding + fileNameWidth
}
fmt.Fprintln(w)