Go(present)でプログラムが実行できるスライド作ってみる

# はじめに
スライドを作る時に、大抵はgoogleスライドかパワーポイントを使うと思います。僕もそうです。GUI操作で簡単に作れますし、多くを覚えなくても作れることはすごく楽です。  
ですが、スライド上でプログラムを実行したい場面がきっとあるはずです(こじつけ)。そこでGoの`present`を使うことで、リアルタイムにプログラムを実行してみます。

## 動作イメージ
![画面収録-2023-11-25-17-imageonline.co-4052414.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1939085/c067e7f1-aa4f-b06c-9d52-14835e97318b.gif)

こんな感じで`present`を使うことで、プログラムが実行できるスライドが作れます。

## フォルダ構成
スライド上でプログラムが実行できれば目標は達成ですが、せっかくなのでスライドっぽく何枚か作りました。
```
── .
   ├─ image
   │   ├─ golang.png
   │   └─ python.png
   ├─ src
   │   ├─ fetch.py
   │   ├─ main.py
   │   ├─ sample.go
   │   └─ sample.py
   ├─ go.mod
   ├─ go.sum
   └─ main.slide
```
`image`は、ローカル上でスライドに貼り付けたい画像を入れています。ネット上にある画像のURLを直接指定して、描画することもできるみたいです。  
`src`は、実行したいファイルを置きました。  

別にフォルダ構成にルールはなく、スライドを作る段階で、画像やプログラムのパスを指定するので、ぶっちゃけどんなでも大丈夫です。

## `present`の環境を作る
[Goのpresentで発表用スライドを作成する](https://christina04.hatenablog.com/entry/2016/10/04/193000)という記事を参考にしました。  
また、`present`の使い方に関する[ドキュメント](https://pkg.go.dev/golang.org/x/tools/present)も用意されています。  
　
僕の実行環境は以下の通りです。
* go 1.20.7
* M2 macOS 13.3.1

---

Goのインストールが終わっていれば、ターミナルで以下のコマンドを実行。
```
% go mod init 'プロジェクト名'
% go install golang.org/x/tools/cmd/present@latest
```
パスを通します。僕のターミナルはzshなので、`~/.zshrc`の中に以下を追記しました。
```
export PATH=$PATH:$HOME/go/bin
```
あとは、ターミナル上で`present`と実行すると、ローカルホストの3999ポートが起動するので、ブラウザ上でスライド画面が見れるようになります。  
拡張子`.slide`というファイルがスライドとして認識されるので、僕は`main.slide`という名称のファイルを作りました。そこに、スライドの内容を記述していきます。  

## スライド作り
```main.slide
# プログラムが実行できるスライドを作ってみた

　
T_death
2023年12月9日

https://qiita.com/T_death

## goファイルを実行してみる
: goファイルであれば、for文を逐次出力できる

sample.go

.play ./src/sample.go
.image ./image/golang.png 100 100

## pythonを実行してみる
: pythonファイルは、なぜかfor文を逐次ではなく、一気に出力する

sample.py

.play ./src/sample.py
.image ./image/python.png 100 _

## APIサーバーを叩いてみる
: golangじゃなくても、リアルタイムに実行ができる

FastAPIでAPIサーバーを構築 & `localhost:8000`で起動

.code ./src/main.py

`urllib`を使って、APIを叩いてみる

.play ./src/fetch.py
```
`.slide`の記述の方法に関しては、用意されている[ドキュメント](https://pkg.go.dev/golang.org/x/tools/present)で詳しく知ることができます。  
ここでは、僕が気づいた点をまとめてみます。
* `#`がスライドのタイトル
    * ここに書く内容が、スライドの冒頭と最後に反映される
    * 各種SNSやサイトのリンクを貼ることができるが、これは最後のスライドにのみ反映される
    * いい感じに空行を挟みたい場合は、全角スペースを入れるしかないかも
    * 最後のスライドの「Thank you」は変更不可
* `##`は各スライドの見出し
    * 新しいスライドとして認識される
    * なので、スライドを新規作成するときに使う
* 画像を添付できる
    * ただし、位置は左右中央で固定
    * 画像サイズは、縦横のサイズを指定できる
        * `_`を使うことで、縦横比を保ちつつサイズの調整が可能
* ソースコードを添付できる
    * ソースコードを添付するだけも可能
    * ソースコードを実行することも可能
        * これが一番のお目当て
        * Goに限らず、他のプログラミング言語でも実行できる
            * ソースコードの冒頭に、実行したい言語のパスを指定してあげる必要がある
    * ソースコードの添付/実行に関わらず、記述するときは、手前に1行空行が必要
        * そうしないとスライドに反映されなくなる

## 最終的にできたスライド
![画面収録-2023-11-25-18-imageonline.co-8003715.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1939085/46efcb8a-549a-23d8-570c-cba468dea20a.gif)

* スライドは見れるけれど、プログラムの実行がうまくいかない場合
    * ブラウザで`http://localhost:3999`とアクセスしている場合は、`http://127.0.0.1:3999`としてアクセスするようにする
* 逐次処理の出力が言語によって異なる
    * Goのfor文は逐次出力されたが、Pythonだとなぜか最後にまとめて出力された
    * Pythonの`logging`を使うと、一応逐次出力できた
* スライドに掲載するソースコードは省略可能
    * ソースコードが長い場合は、一部のみにできる

# おわりに
Goの`present`を使って、プログラムの実行ができるスライドを作ってみました。  
Go以外の言語も実行できて、Goを書くと言うよりは、`.slide`の中をmarkdownっぽく書く感じだったので、難しくなかったです。  
添付したい画像の位置が選べない点が、結構痛手だと感じてしまいました。テキストと並べるということは難しそうですが、せめて左右中央以外の横軸上で選択できたらなぁ、と思いました。  
ですが、僕はスライドを作るデザインセンスがまるで皆無なので、`present`を使うことにより、できることに制限がある方が、かえってデザインを気にしなくて良い点は、大変喜ばしいです。