良い感じにスライドを作れる Talkie をラップした talkiego を作った
ここのところ、プレゼン用スライドの制作は @ahomu さん製の Talkie をお借りしているのですが、 Talkie はソースを丸っと落として index.html を編集する必要があります。
Markdown だけ記述してコマンド一発で起動できるようにしたかったので talkiego を作りました。
Talkie とは
ahomu/Talkie: Simple slide presentation library. Responsive scaling & markdown ready.
Talkie は @ahomu さん製の良い感じにおしゃれなスライドを作れるライブラリです。
似たようなツールとして reveal.js があるのですが、個人的には Talkie の方が日本語のレイアウトが綺麗に決まるので Talkie を愛用しています。
reveal.js でもダメではないのですが、ちょっと真ん中にギュッと寄ってしまう感がありまして、好みではなかったです。
talkiego とは
talkiego は Markdown ファイル単体を引数で取れば Talkie で起動してくれるツールです。
reveal.js でいうところの yusukebe/revealgo です。
作った経緯
Talkie は Node.js 製で、使用するには index.html の編集が必要になります。 slide を作るときに丸っと Talkie を落として編集するのではなくコンテンツ部分だけ書かれた Markdown ファイルを読み込むようにしたかったのが動機です。
talkie.js、単体mdファイルから錬成できるようなラッパー欲しくなってきた
— hori (@hori_ryota) June 17, 2017
https://t.co/WLcueJxxGs こういうの?
— あほむ|副業転職 Offers の overflow (@ahomu) June 17, 2017
ですです。同ディレクトリに各ファイル展開するのではなく、mdと必要なimgだけ配置しておいてコマンドだけ叩けば表示できるような
— hori (@hori_ryota) June 17, 2017
ああ、なるほろ
— あほむ|副業転職 Offers の overflow (@ahomu) June 17, 2017
がっつりプレゼン資料作るだけじゃなくてペライチ提出にも使いたくなったので、Decksetばりに気軽に書き捨てできるようなとこまで頑張ってみようかなと
— hori (@hori_ryota) June 17, 2017
まじか、期待してる
— あほむ|副業転職 Offers の overflow (@ahomu) June 17, 2017
まだ色々途中ですが一旦作りました。
— hori (@hori_ryota) June 18, 2017
talkiego serve hoge.md
で表示できて満足です∠( ゚д゚)/
"hori-ryota/talkiego"https://t.co/e1eBtI69n9
あゆむさんレビュー通ったらブログ書きます…!
ウゴイタアアア!
— あほむ|副業転職 Offers の overflow (@ahomu) June 19, 2017
極端に言ったらカスタムテンプレート利用できればどうとでもなりそうだね👌
使い方
talkiego の README.md に書いてありますが、簡単に載せておきます。
Talkie の index.html だとこんな感じで書きますが、
<html>
<head>
<meta charset="utf-8">
<title>Talkie.js - HTML/CSS/JavaScript Presentation Library</title>
<link rel="stylesheet" href="./dist/talkie.min.css">
<link rel="stylesheet" href="./dist/talkie-default.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/monokai_sublime.min.css">
</head>
<body>
<!-- put your slides -->
<template layout="cover" type="text/x-markdown">
# Talkie.js
</template>
<template layout="title" invert type="text/x-markdown"
backface="https://farm8.staticflickr.com/7469/16209884502_211d01ac0d_z_d.jpg"
backface-filter="blur(3px) brightness(.9)">
# Backface (北極)
</template>
<script layout="bullets" type="text/x-markdown" style="color:#ff0000;">
* foo
* bar
* baz
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script>
<script src="./dist/talkie.min.js"></script>
<script>
var talkie = Talkie({
wide: true,
control: true
});
document.addEventListener('DOMContentLoaded', function() {
talkie.changed.subscribe(function(current) {
console.clear();
// print presenter notes
console.info(talkie.notes[current.getAttribute('data-page')]);
});
});
</script>
</body>
</html>
talkiego だとこうなります。
<!-- rootopt: wide control -->
<!-- cover: -->
# Talkie.js
---
<!-- title: invert
backface=https://farm8.staticflickr.com/7469/16209884502_211d01ac0d_z_d.jpg
backfaceFilter="blur(3px) brightness(.9)" -->
# Backface (北極)
---
<!-- bullets: style="color:#ff0000;" -->
* foo
* bar
* baz
で、この作った Markdown ファイル (index.md) を引数にとって起動します(デフォルト値は index.md にしてあります)。
talkiego serve index.md
backface などのオプションの記述は必要ですが、コンテンツだけを独立した Markdown ファイルにできました。
Markdown ファイルだけなので、企画案などのペライチを量産するときにもとても捗ります。
実装について
とりあえずコマンドなのでベースは spf13/cobra を使用しました。
Talkie は Node.js ですが、スライドを動かすには dist ディレクトリに生成される静的ファイルを用いれば Node サーバの起動はしなくても動かせます。よって今回は jessevdk/go-assets で Talkie のデフォルトテンプレートファイルを Go のソースコードにバイナリとして埋め込み、 FileServer として使用することでファイルを返せるようにしました。
assets 系の埋め込みは jteeuwen/go-bindata も人気ですが、今回はシンプルにファイルサーバとして使用するので http.FileSystem
の実装を持っている jessevdk/go-assets を使用しています。
大変だったところ
オプションのダブルクォーテーションをオプショナルにしたため、 parser を自作する羽目になりちょっと苦労しました。複数行も対応したため、空白で分割した後に quoted 状況に応じて結合したりなどなど。 CSV ファイルを扱うときもそうなのですが、良い感じでダブルクォーテーションを扱ってくれるライブラリが欲しいところです。
func parseProps(s string) map[string]string {
dst := map[string]string{}
fs := strings.Fields(s)
for i := 0; i < len(fs); i++ {
// split key:value or key=value
sep := strings.IndexAny(fs[i], ":=")
if sep < 0 {
dst[fs[i]] = ""
continue
}
k, v := fs[i][:sep], fs[i][sep+1:]
if !strings.HasPrefix(v, "\"") {
dst[k] = v
continue
}
// quoted
i++
for i < len(fs) {
v = fmt.Sprintf("%s %s", v, fs[i])
if strings.HasSuffix(fs[i], "\"") && !strings.HasSuffix(fs[i], "\\\"") {
break
}
i++
}
dst[k] = strings.Trim(v, "\"")
}
return dst
}
とりあえず必要な書式で動けばいいやーと思いざっくり実装にしてあるので、正確な quoted の挙動にはなっていないかもしれませんが、及第点としたいところ。
今後の展望
このへんはあると便利だなーと思ってはいますが、とりあえず自分はデフォルトテンプレートがあれば困っていないのでどうしようかなと。
- Talkie のディレクトリを指定すると埋め込んだ assets ではなく指定した Talkie を見る
- Talkie のオプション(
wide
など。勝手に RootOpt と呼んでいる)をコマンド引数で指定できるように - watch オプションで変更検知
- カスタム CSS ファイルなどを読み込めるように
- HOME ディレクトリらへんにコンフィグファイルを置いて、デフォルト設定として用いる
- オプションのエイリアスやシンボル、モジュール化
プルリクお待ちしております。
以上
スライドを作らなければいけないと思うと急にツールを整えたくなる病でカッとなって作ったのですが、狙い通り便利なものができたので捗っています。
デザインセンスが無いので、ネタだけ用意すれば見た目はそれっぽくしてくれるツール群は本当に助かります。ありがとうございます。