Help us understand the problem. What is going on with this article?

CircleCIでmarkdownからスライド資料を自動生成する

More than 3 years have passed since last update.

先日初めてLTというものをする機会がありましたので、せっかくだし楽にスライド資料を作れる仕組みを作ってしまおうと思ったのが動機になります。

実現したかったこと

  • markdownで資料を作成してgit pushするとCircleCIがスライド資料に起こしてくれる。
  • スライド資料はGitHub Pagesで公開され、そのまま発表に使える。
  • ついでにCircleCI上で文法上の誤りもテストしてくれる。

実現方式

markdownからのスライド生成

reveal.jsが有名かと思いますが、それをRubyGem化して、コマンド一発だけでmarkdownからスライド資料への変換を可能にしたreveal-ckを使います。

markdownはほぼGitHub Flavored markdownで大丈夫(絵文字もOK)ですが、---でページ区切りになるという点だけ覚えておけばよいかと。

GitHub Pagesへの公開

2016年8月のアップデートで、GitHub Pagesへの公開方法が以下の3つになりました。

  • masterブランチの/docsフォルダ内をPagesとして公開する。
  • masterブランチをPagesとして公開する。
  • gh-pagesブランチをPagesとして公開する(従来の方法)。

スライド用に生成されたファイルをフォルダに押し込める形で実現できそうなので、当初は/docsフォルダを使う方法を検討していましたが、スライドのGitHub Pages上での公開は発表のときだけ使えればよかったので、そういう一時的な用途でmasterブランチを使うのは微妙だなと見直し。またCircleCIからmasterブランチを書き換えるというのも抵抗があったので、CircleCIではgh-pagesブランチをcheckoutさせる形にしました。

文章校正

最近流行りの分野ではありますが、定番のtextlintを使いました。textlint自体初めて使ったということもあり、以下の記事を大いに参考とさせていただきました。

実装

レポジトリ内は以下の構成になりました。

|-- .textlintrc
|-- circle.yml
|-- package.json
`-- (スライド用ディレクトリ)
    |-- slides.md
    `-- config.yml

トップにはCircleCIを設定するためのcircle.ymlと、textlintを導入するためのpackage.json、textlintの設定を書いた.textlintrcの3ファイルを置きます。package.jsonと.textlintrcの設置については先のリンク記事の内容ほぼそのまんまですが、以下の手順で生成しています。いずれもレポジトリのトップの場所で実行します。

# package.jsonを生成します。
$ npm init
# textlint等をインストールし、package.jsonに依存関係を記述。
$ npm install --save textlint textlint-rule-common-misspellings textlint-rule-preset-japanese
# node_modulesにtextlint等がインストールされますが、
# 実際はCircleCI上で逐次インストールして使うので、レポジトリからは削除していいです。
$ rm -rf node_modules
# package.jsonのscriptsにtextlint実行用のコマンドを記載しておきます。後述。
$ vim package.json
# .textlintrcは手動で生成して、後述の通り記載します。
$ vim .textlintrc

package.jsonは以下のように、scriptsにtextlint実行用のコマンドを記載しておきます。これでnpm run textlint (対象ディレクトリ)で、指定したディレクトリ内のmarkdownファイルに対してtextlintが実行されます。

package.json
{
  "private": true,
  "scripts": {
    "textlint": "textlint -f pretty-error"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/chroju/talks.git"
  },
  "dependencies": {
    "textlint": "^7.1.2",
    "textlint-rule-common-misspellings": "^1.0.1",
    "textlint-rule-preset-japanese": "^1.3.3"
  }
}

.textlintrcには適用する校正ルールを記載します。

.textlintrc
{
  "rules": {
    "common-misspellings": true,
    "preset-japanese": true
  }
}

続いてcircle.ymlは以下の通り。

circle.yml
general:
  branches:
    ignore:
      - gh-pages
      - master

machine:
  timezone:
    Asia/Tokyo
  ruby:
    version:
      2.3.1
  node:
    version:
      7.0.0

dependencies:
  cache_directories:
    - "/opt/circleci/.rvm/gems"
    - "/home/ubuntu/talks/node_modules"
  pre:
    - gem install reveal-ck --no-ri --no-doc
    - npm install

test:
  override:
    - npm run textlint $CIRCLE_BRANCH
  post:
    - cd /home/ubuntu/talks/$CIRCLE_BRANCH && reveal-ck generate && cp -r slides/* ../

deployment:
  github:
    branch: /.*/
    commands:
      - git config --global user.name chroju
      - git config --global user.email chor.chroju@gmail.com
      - rm .ruby-version
      - git checkout gh-pages
      - git add --all
      - git commit -m "Circle CI deploy"
      - git push git@github.com:chroju/talks gh-pages

まずdependenciesでreveal-ckとtextlintをそれぞれインストールしています。textlintに関してはpackage.jsonに依存関係を書いているので、npm installだけで入ります。一度インストールしてしまえばその後は使いまわせるので、cache_directoriesに指定してキャッシュしておきます。

参考:Caching RubyGems Install - Programming Languages - CircleCI Community Discussion

testではnpm run textlint $CIRCLE_BRANCHでoverrideし、textlintを実行します。失敗するとこんな感じに。

textlint failure

なお、overrideに記載している通り、textlintの対象ディレクトリ名は、$CIRCLE_BRANCH変数でブランチ名から取ってきています。つまり新たにスライド資料を作成するときは、以下の手順になります。

  1. ブランチを新しくつくる(ブランチ名は発表するイベント名や、スライドタイトルがオススメ)。
  2. ブランチ名と同名のディレクトリを作成する。
  3. 作成したディレクトリ内にslides.mdを置き、資料を作成する。

testpostでは、このブランチ名のディレクトリに移動してreveal-ck generateを実行し、スライド資料を作成しています。作成されたファイル群はslidesフォルダの中に置かれますが、これをトップへcpしているのは、GitHub Pagesで公開したときにトップのパスで資料が見られるようにするためです。

textlintが通ればdeploymentに移行し、gh-pagesブランチを生成してpushして完了です(逆に言えばtestが通らなければ、deploymentは実行されません)。ここまで無事に終われば、GitHub Pagesでスライド資料が見られるようになっているはずです。ブラウザでアクセスして、全画面表示にすればそのまま発表に使えます。

発表が終わったらgh-pagesブランチは削除し、スライド用ブランチをmasterにマージしてあげれば完了です。

補足

スライドの外観を変更したい

reveal.jsのスライドの外観は、slides.mdと同じ場所に置いたconfig.ymlによって設定できます。主にテーマ(色やフォント)とtransition(ページめくりのアニメーション)が変更でき、テーマの一覧は http://lab.hakim.se/reveal-js/#/themes 、transitionの一覧は http://lab.hakim.se/reveal-js/#/transitions から確認できます。またtitleを指定すると、GitHub Pagesで開いたときのページタイトルがそれになります。

config.yml
theme: "white"
transition: "none"
author: "chroju"
title: "ポエム駆動開発"

スライドをpdfで保存したい

これはreveal.jsが機能を持っています。GitHub Pagesでスライドのトップを開いたら、URL末尾にindex.html?print-pdfを付加して開き直し、印刷画面から「PDFで保存」します。保存するとき、ページの向きは「横」にします。

参考:reveal.js で pdf 印刷

完成品

GitHubに上げています。

chroju/talks: LTs

masterブランチのものは私のLT資料を入れているので個人用ですけど、個人的なものを削除したreleaseブランチを用意しているので、そちらをフォークしてもらえればここに書いたとおりのことがすぐに実行できるはずです。詳しくはREADME.md参照で。

chroju
Site Reliability Engineer loves Terraform, Go, AWS
https://chroju.dev
globis
グロービスは 1992 年の創業以来、社会人を対象とした MBA、人材育成の領域で Ed-Tech サービスを提供し、現在は日本 No.1 の実績があります。これらの資産と、さらに IT や AI を活用することで、アジア No.1 を目指しています。
http://www.globis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away