Why not utilize an ability to provide a custom renderer to do some arbitrary requests on the backend? Let’s get Gemini client and just parse the GMI contents just into a code block.
You can follow the following tutorial to find out how to implement your custom renderer for vpub-plus: https://vpub.mysh.dev/topics/17
Code
We will create custom RenderNode
implementation from blackfriday.Renderer
to find our gemini link in the forum post and then do something with it.
As for gemini client, we will use Gemax:
type geminiLinkRenderer struct {
blackfriday.Renderer
}
func (r *geminiLinkRenderer) RenderNode(
w io.Writer,
node *blackfriday.Node,
entering bool,
) blackfriday.WalkStatus {
if node.Type != blackfriday.Text {
return r.Renderer.RenderNode(w, node, entering)
}
if !bytes.HasPrefix(node.Literal, []byte("gemini://")) {
return r.Renderer.RenderNode(w, node, entering)
}
node.Type = blackfriday.CodeBlock
cl := gemax.Client{}
resp, err := cl.Fetch(context.Background(), string(node.Literal))
if err != nil {
node.Literal = []byte("Errored when tried to fetch gemini site: " + err.Error())
return r.Renderer.RenderNode(w, node, entering)
}
data, err := io.ReadAll(resp)
if err != nil {
node.Literal = []byte("Errored when tried to read from gemax client reader: " + err.Error())
return r.Renderer.RenderNode(w, node, entering)
}
node.Literal = data
return r.Renderer.RenderNode(w, node, entering)
}
[... somewhere in there is an embed into a renderer ...]
And this is what we ended up with:

Funny. I wonder how it would look like if we transform GMI into HTML nodes?