feat(image): basic iTerm image protocol support
This commit implements the function requested in issue #175.
Currently, only the iTerm image protocol is supported. Some code from muesli/reflow is copied & manually patched, so wrapping and indentation will not interfere with the iTerm escape sequence (which is not quite the same as the ANSI sequences)
This functionality is only enabled if you pass WithImageDisplay() when creating a new TermRenderer. You also need to specify the BaseURL with WithBaseURL(path), where path ends with a slash.
I have verified that it works under WezTerm. If the terminal is not supported, it will automatically switch to the old rendering mode of images as fallback.
For more details, please see TestImageDisplay in glamour_test.go .
I'm happy to integrate any modification from the maintainers into my code.
This shall close #175 if merged.
Hey. I've been testing this with WezTerm, even going as far as setting $TERM_PROGRAM to iterm.app.
Unfortunately, it doesn't display the expected result but rather just the file name.
go.mod
require github.com/charmbracelet/glamour v0.6.0
replace github.com/charmbracelet/glamour => github.com/panda2134/glamour v0.0.0-20221019190525-0a12aed65d12
main.go
package main
import (
"fmt"
"os"
"github.com/charmbracelet/glamour"
)
// TODO: Add proper syslogging
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
fileName := os.Args[1:]
file, err := os.ReadFile(fileName[0])
check(err)
os.Setenv("TERM_PROGRAM", "iterm.app")
r, _ := glamour.NewTermRenderer(
glamour.WithStandardStyle("dark"),
glamour.WithImageDisplay(),
)
// TODO: Find a way to add padding (<br/>) between bullet points
out, _ := r.Render(string(file))
fmt.Print(out)
}
test.md
Alice(1) -- A modern manpage viewer alternative
=============================================

I previously checked that WezTerm's iTerm2 image support works through the imgcat tool by olivere (which it does).
Hey. I've been testing this with WezTerm, even going as far as setting
$TERM_PROGRAMtoiterm.app.Unfortunately, it doesn't display the expected result but rather just the file name.
go.mod
require github.com/charmbracelet/glamour v0.6.0 replace github.com/charmbracelet/glamour => github.com/panda2134/glamour v0.0.0-20221019190525-0a12aed65d12main.go
package main import ( "fmt" "os" "github.com/charmbracelet/glamour" ) // TODO: Add proper syslogging func check(e error) { if e != nil { panic(e) } } func main() { fileName := os.Args[1:] file, err := os.ReadFile(fileName[0]) check(err) os.Setenv("TERM_PROGRAM", "iterm.app") r, _ := glamour.NewTermRenderer( glamour.WithStandardStyle("dark"), glamour.WithImageDisplay(), ) // TODO: Find a way to add padding (<br/>) between bullet points out, _ := r.Render(string(file)) fmt.Print(out) }test.md
Alice(1) -- A modern manpage viewer alternative ============================================= I previously checked that WezTerm's iTerm2 image support works through the imgcat tool by olivere (which it does).
Hi! Please look at glamour_test.go. You need to add an option called WithImageDisplay. As you've added it there might be something wrong with the logic. I'll check it on my side.
Hey. I've been testing this with WezTerm, even going as far as setting
$TERM_PROGRAMtoiterm.app. Unfortunately, it doesn't display the expected result but rather just the file name. go.modrequire github.com/charmbracelet/glamour v0.6.0 replace github.com/charmbracelet/glamour => github.com/panda2134/glamour v0.0.0-20221019190525-0a12aed65d12main.go
package main import ( "fmt" "os" "github.com/charmbracelet/glamour" ) // TODO: Add proper syslogging func check(e error) { if e != nil { panic(e) } } func main() { fileName := os.Args[1:] file, err := os.ReadFile(fileName[0]) check(err) os.Setenv("TERM_PROGRAM", "iterm.app") r, _ := glamour.NewTermRenderer( glamour.WithStandardStyle("dark"), glamour.WithImageDisplay(), ) // TODO: Find a way to add padding (<br/>) between bullet points out, _ := r.Render(string(file)) fmt.Print(out) }test.md
Alice(1) -- A modern manpage viewer alternative ============================================= I previously checked that WezTerm's iTerm2 image support works through the imgcat tool by olivere (which it does).
Hi! Please look at
glamour_test.go. You need to add an option calledWithImageDisplay. As you've added it there might be something wrong with the logic. I'll check it on my side.
Thanks for looking into it.
glamour_test.go is where I got the glamour.WithImageDisplay() and os.Setenv("TERM_PROGRAM", "iterm.app") from.
Hey. I've been testing this with WezTerm, even going as far as setting
$TERM_PROGRAMtoiterm.app. Unfortunately, it doesn't display the expected result but rather just the file name. go.modrequire github.com/charmbracelet/glamour v0.6.0 replace github.com/charmbracelet/glamour => github.com/panda2134/glamour v0.0.0-20221019190525-0a12aed65d12main.go
package main import ( "fmt" "os" "github.com/charmbracelet/glamour" ) // TODO: Add proper syslogging func check(e error) { if e != nil { panic(e) } } func main() { fileName := os.Args[1:] file, err := os.ReadFile(fileName[0]) check(err) os.Setenv("TERM_PROGRAM", "iterm.app") r, _ := glamour.NewTermRenderer( glamour.WithStandardStyle("dark"), glamour.WithImageDisplay(), ) // TODO: Find a way to add padding (<br/>) between bullet points out, _ := r.Render(string(file)) fmt.Print(out) }test.md
Alice(1) -- A modern manpage viewer alternative ============================================= I previously checked that WezTerm's iTerm2 image support works through the imgcat tool by olivere (which it does).
Hi! Please look at
glamour_test.go. You need to add an option calledWithImageDisplay. As you've added it there might be something wrong with the logic. I'll check it on my side.Thanks for looking into it.
glamour_test.gois where I got theglamour.WithImageDisplay()andos.Setenv("TERM_PROGRAM", "iterm.app")from.
I figured it out finally. You need to set the BaseURL in glamour like this:
dir, _ := os.Getwd()
r, _ := glamour.NewTermRenderer(
glamour.WithStandardStyle("dark"),
glamour.WithBaseURL(dir + "/"),
glamour.WithImageDisplay(),
)
After correctly setting the BaseURL (ending with "/") you'll see the image rendered. I probably forgot to mention this requirement, sorry for that.
Hey. I've been testing this with WezTerm, even going as far as setting
$TERM_PROGRAMtoiterm.app. Unfortunately, it doesn't display the expected result but rather just the file name. go.modrequire github.com/charmbracelet/glamour v0.6.0 replace github.com/charmbracelet/glamour => github.com/panda2134/glamour v0.0.0-20221019190525-0a12aed65d12main.go
package main import ( "fmt" "os" "github.com/charmbracelet/glamour" ) // TODO: Add proper syslogging func check(e error) { if e != nil { panic(e) } } func main() { fileName := os.Args[1:] file, err := os.ReadFile(fileName[0]) check(err) os.Setenv("TERM_PROGRAM", "iterm.app") r, _ := glamour.NewTermRenderer( glamour.WithStandardStyle("dark"), glamour.WithImageDisplay(), ) // TODO: Find a way to add padding (<br/>) between bullet points out, _ := r.Render(string(file)) fmt.Print(out) }test.md
Alice(1) -- A modern manpage viewer alternative ============================================= I previously checked that WezTerm's iTerm2 image support works through the imgcat tool by olivere (which it does).
Hi! Please look at
glamour_test.go. You need to add an option calledWithImageDisplay. As you've added it there might be something wrong with the logic. I'll check it on my side.Thanks for looking into it.
glamour_test.gois where I got theglamour.WithImageDisplay()andos.Setenv("TERM_PROGRAM", "iterm.app")from.I figured it out finally. You need to set the BaseURL in glamour like this:
dir, _ := os.Getwd() r, _ := glamour.NewTermRenderer( glamour.WithStandardStyle("dark"), glamour.WithBaseURL(dir + "/"), glamour.WithImageDisplay(), )After correctly setting the BaseURL (ending with "/") you'll see the image rendered. I probably forgot to mention this requirement, sorry for that.
Looks like we figured it out at the exact same time. Hehe. I just saw there was an error message in the log, so I realized it was a pathing issue too. Worked with an absolute path, but PWD is obviously better.
if the repo owner is still interested in this pr, I'll be happy to fix those conflicts.