
Present with Go Modules
There are a few quite interesting utilities in the Go Tools collection, golang.org/x/tools
.
One of these is the slide presentation software present
.
$ go install golang.org/x/tools/cmd/present@latest
If you have watched any Go presentations in the past, there is quite a chance you have already seen present
in action.
For example, many of Rob Pike’s talks are using present
, e.g., his talk on lexical scanning.
present
renders Markdown-ish files to either slides or articles - such as for the Go blog - to be displayed in a web browser.
Although the feature set is limited, one killer feature is the ability to execute code directly from the slides.
The golang.org/x/tools/present
package describes the anatomy of a .slide
input file and all available commands.
.play
Some Code
The mentioned code execution killer feature is named .play
and allows not only embedding code, but actually executing this code.
For example, the following line in a .slide
file would display the content of some demo.go
file, make the text box editable, and allow the code to be executed.
.play -edit demo.go
Earlier this year, I have used this for my “Privilege Separation In Go” talk at FOSDEM. At around the 02:00 mark in the linked talk, you can see me altered the code to demonstrate the privileges with which the code usually runs.
Later in the talk, I showed multiple Go libraries that I used directly within present
.
This, however, was quite a hassle since present
- being an older, not so official Go tool - still relies on the $GOPATH
.
Since time was not on my side, I have ended up filling the $GOPATH
manually.
And all this over six years after Go 1.11, deep in the age of Go Modules.
Since I was planning to work with external libraries in present
again, I settled to patch it in this regard.
Just to find out that it can already do this.
.play
Me A Go Module
The .play
command works not only on Go code, but also on the txtar
archive format, which I just learned about today (actually, it was yesterday - I am now finishing this post).
In a nutshell, it is a plain text format concatenating multiple text files, each being introduced by a -- FILENAME --
marker, with FILENAME
being the actual file name.
There may also be a comment before the first file’s marker.
The .play
ed file will be parsed as a txtar
archive.
If the file is an ordinary Go source code file, there will be no marker and everything is part of the leading comment.
A non-empty comment will then be treated as a prog.go
file.
However, if the input contains txtar
entries, each one will be created.
Additionally, if a go.mod
file is included in the txtar
input, the Go code will be built as a Go Module.
In practice, this looks like the following. For example’s sake, I am using the SHA-3 TupleHash library I wrote a while back.
$ go mod init demo
go: creating new go.mod: module demo
$ cat main.go
package main
import (
"fmt"
"codeberg.org/oxzi/go-tuplehash"
)
func main() {
fields := [][]byte{[]byte("foo"), []byte(""), []byte("bar")}
h := tuplehash.NewTupleHash128(nil, 32)
for _, field := range fields {
_, _ = h.Write(field)
}
fmt.Printf("%x\n", h.Sum(nil))
}
$ go get codeberg.org/oxzi/go-tuplehash
[ . . . ]
$ go build
$ cp main.go demo.txtar
$ for f in go.{mod,sum}; do echo "-- $f --"; cat "$f"; done >> demo.txtar
This can be demonstrated with a simple .slide
file as follows.
The /^func main/,/^}/
part behind the .play
calls reduces the printed output to the main
function for aesthetic reasons.
# External Module Test
## Go File - Fails
.play main.go /^func main/,/^}/
## Go File from txtar - Works
.play demo.txtar /^func main/,/^}/

First, present fails due to missing packages - as expected.

The second example based on txtar works and produces a hopefully valid output.
.play
Me Any Script
While poking through the playground socket code, I made another unexpected discovery: shebang support!
If the code starts with a shebang (#!
), then it will not be compiled as a Go application, but executed by the shebang interpreter.
Therefore, present
can be used to run almost any code.
Let’s demonstrate this with an even simpler example of the following .slide
:
# Shebang Test
## Python
.play -edit demo.py
And demo.py
looking like this:
#!/usr/bin/env python3
import this

present executing a Python script running the PEP 20 easter egg.
Swimming Upstream Is Hard
First and foremost, a random blog post should not be the place to document implementation behavior. Documentation should be, well, in the docs. I have created a pull request, so let’s see how it turns out.
Google’s contribution maze for Go typically guides one through their Gerrit code review tool.
Last time I have used it was roughly two years ago and, of course, it requires a Google account.
And this was also the last time I have used my Google account, which still has a @googlemail.com
address instead of @gmail.com
.
What’s my age again?
When I tried to log in to this account, Google blocked the login because it thought there was something suspicious about me. As so called “options” to unblock the account, I should either use the same device or a similar location as last time - I have moved roughly 300km. That’s all, no other options.
No Gerrit for me today. This is just another downsides of big tech FOSS projects.
It’s Not A Bug, It’s A Feature
When people ask me what I like about Go, I usually mention its well documented API.
As being part of the /x/
namespace, the Go Tools are not so official, but once I became accustomed to the high quality documentation, their lack stood out.
And in this case, it misses two very special cases of executing code.
Taking a look at the txtar
extraction logic is also a bit scary.
Yes sir, I would like you to extract ../../../../../etc/passwd
.
This has only no further security implications as arbitrary user-supplied code will be executed next.
Thus, do not let present
run wild and only execute trusted .slides
.
Speaking of undocumented behavior, I tried the same thing in the Go Playground and was quite surprised that the txtar
trick worked there as well.
Unlike the other code, the Go Playground has some input sanitation in place.
Unfortunately, there seems to be no shebang support.

Go Module in the Go Playground as txtar encoded input.
All The Negativity?
The last two sections turned out quite bitter, and I failed to find a way to change that.
However, I wanted to end on a positive note and emphasize one more time that I really enjoy working with present
.
It is a fantastic tool, especially for presentations with code.
Use it!