xaringanによるスライド作成入門


  - 元ネタ: <https://bookdown.org/yihui/rmarkdown/xaringan-start.html>
    - 順序とかはチョット変えました
  - ライセンス: CC BY-NC-SA 4.0

## 1 はじめに

`xaringan`はJavaScriptライブラリの`remark.js` (<https://remarkjs.com>)を用いてHTML5のプレゼンテーションを作成するRのパッケージです。`xaringan`を使うとこんな感じのスライドが作成できます。

![fig0-1_xaringan_preview.png](https://qiita-image-store.s3.amazonaws.com/0/109348/fb114c0d-06d8-a85b-25ef-39cad646206e.png)
![fig0-2_xaringan_preview2.png](https://qiita-image-store.s3.amazonaws.com/0/109348/2ebdbec2-3bd6-69d9-65fb-d6f773022d82.png)

このパッケージの名前は「ナルト」の写輪眼から来ています。これは発音のしづらさと、作者が非常に気に入っているこのスタイルが「有名になりすぎる」のを懸念したため採用されたそうです（昨今の学会はLaTeX Beamerを使ったスライドばかりなので、作者はBeamerの使用をやめたそうです）。そんな心配をよそに、`xaringan`は非常に柔軟なカスタマイズが可能であるため、現在ではユーザーが作成した独自のスタイルもコントリビュートされるようになっています。

`remark.js`はMarkdownしかサポートしませんが、`xaringan`はR Markdownのサポートを追加し、さらにスライドの作成とプレビューを容易にするいくつかのツールも付け加えました。

パッケージにまつわる背景や、使い方についてもう少し詳しく知りたければ、`xaringan`によって作成されたスライドである[Presentation Ninja](https://slides.yihui.name/xaringan/#1)を見てみると良いでしょう。また、作者がなぜ`xaringan`/`remark.js`を用いたHTML5プレゼンテーションにこだわるかを知りたければ作者のブログ記事[Why xaringan / remark.js for HTML5 Presentations? - Yihui Xie | 谢益辉](https://yihui.name/en/2017/08/why-xaringan-remark-js/)を読んでみるのも良いかもしれません。

## 2 パッケージのインストール

では早速パッケージをインストールしてみましょう。`xaringan`はCRANから取得できます。

``` r
# CRANからインストールするならこちら
install.packages("xaringan")

# GitHubから開発版をインストールするならこちら
# devtools::install_github("yihui/xaringan")
```

パッケージをインストールすると、`File > New File > R Markdown > From Templete`の中に`Ninja Presentation`が出現します。これを選択すると`xaringan`パッケージを使ったスライドをテンプレートから作り始めることができます。まずはこれを選択してそのままknitしてみると良いでしょう。

このパッケージによるR Markdownの出力フォーマットは`moon_reader()`で定義されています。したがって、可能な設定のすべては、`?xaringan::moon_reader`から確認できます。

以下は`xaringan`パッケージによるスライドを生成する.Rmdファイルの簡単な例です。

``` md
---
title: "スライドタイトル"
subtitle: "スライドサブタイトル"
author: "氏名"
date: "日付"
output:
  xaringan::moon_reader:
    lib_dir: libs
    nature:
      highlightStyle: github
      countIncrementalSlides: false
---

一枚目のスライド。

---

二枚目のスライド。
```

## 3 スライドのフォーマット

スライドを作成していく前に、`remark.js`や`xaringan`、Pandocの関係について簡単に説明しておきます。

[remark.jsのWiki](https://github.com/gnab/remark/wiki)には、スライドの見栄えを調整するための詳細なドキュメントが整備されていますが、`remerk.js`に比べると、`xaringan`はいくつかの点で単純化を行っています。例えば、ユーザーはboilerplate HTMLを準備する必要はありませんし、自動再生は`moon_reader()`のオプションを通じて設定できますし、LaTeX形式の数式もきちんとレンダリングされます。

`remark.js`のMarkdown解釈は、PandocのMarkdownと互換性が無いという点に注意して下さい。つまり、PandocのMarkdownの先進的な機能の中には使えないものがあります（例えば相互参照のための記法である`[@key]`が使えません）。

もし`remark.js`がサポートしてない機能を使用したければ、生のHTMLを記述することもできます。例えば、HTMLテーブルを`knitr::kable(head(iris), 'html')`のように生成して利用することができます。

### 3.1 スライドとプロパティ

スライドとスライドの区切りは3つの連続したダッシュ（`---`）で指定します。スライドのコンテンツには好きなものを含めることができます。つまり、タイトルは無くても構いませんし、逆に任意のレベルのタイトルをいくつでも含めることができます。

スライドには**プロパティ**を設定できます。プロパティには`class`や`background-image`のようなものが含まれ、それぞれのスライドの最初に記述します。例を示します。

``` md
---

class: center, inverse
background-image: url("images/cool.png")

# 新しいスライド

スライドの中身
```

`class`プロパティはスライドを囲むHTMLタグにクラスを設定します。これはCSSを使ってスライドの外観を調整したい場合に利用することができます。例えば、クラス`inverse`に次のようなCSSを設定しておけば、暗い背景に明るい文字色のスライドに変更できます。

``` css
.inverse {
  background-color: #272822;
  color: #d6d6d6;
  text-shadow: 0 0 20px #333;
}
```

これを記述するCSSファイルは、`xaringan::moon_reader`以下の`css`オプションで指定できます。

``` md
---
output:
  xaringan::moon_reader:
    css: "my-style.css"
---
```

ところで、実は`inverse`というクラスは`xaringan`のデフォルトテーマ内で既に定義してあります。したがって、デフォルトのテーマを上書きしたいのでなければ、わざわざcssを書かずとも色調を反転したスタイルで表示されます（実際、タイトルスライドには`inverse`がデフォルトで設定されています）。

`background-image`プロパティを利用すると、スライドの背景画像を設定できます。画像はローカルのものでもオンラインのものでも構いませんが、パスは`url()`の内部に記述する必要があります。背景画像はcssの記法を使ってサイズや位置を調整することもできます

``` md
background-image: url("https://github.com/yihui/xaringan/releases/download/v0.0.2/karl-moustache.jpg")
background-position: center
background-size: contain
```

すべてのプロパティを理解するにはCSSの知識が必要です。

ところで上記の例では、実はインラインで式`xaringan:::karl`を展開してKarl Bromanの画像URLを埋め込んでいます。これは`xaringan`パッケージの有用な機能の一つです。

### 3.2 タイトルスライド

タイトルスライドはYAMLメタデータから自動的に生成される特別なスライドです。タイトルスライドにはタイトル、サブタイトル、著者、日付を含むことができますが、これらはすべて任意の項目です。このスライドには`inverse`、`center`、`middle`、`title-slide`という4つのクラスがデフォルトで設定されます。このスタイルが望ましくなければ、`.title-slide`クラスをカスタマイズするか、YAMLの`nature`オプション以下で`titleSlideClass`オプションを通じて任意のクラスを設定することもできます。

``` md
---
output:
  xaringan::moon_reader:
    nature:
      titleSlideClass: ["right", "top", "my-title"]
---
```

タイトルスライドの生成自体を抑制したければ、`seal`オプションに`false`を指定します。

``` md
---
output:
  xaringan::moon_reader:
    seal: false
---

class: inverse

# 独自タイトル

### 独自著者
```

### 3.3 コンテンツクラス

スライドと同様に、スライド内の**任意の要素**に対しても`.className[content]`といった構文を使うことで好きなクラスを設定することができます。これをコンテンツクラスと称します。

コンテンツクラスは`remark.js`の強力な機能の一つであり、Pandocで実現できない数少ない機能の一つでもあります。基本的には、これによってスライド内のどのような要素であってもCSSによってスタイルを設定することができます。

コンテンツクラスとしての利用に便利な組み込みのクラスも用意されています。例えば`.left[ ]`、`.center[ ]`、`.right[ ]`を利用すると、要素の水平位置を制御できます。画像をセンタリングしたければ次のようにできるわけです。

``` md
.center[![イメージの説明](path/to/image.png)]
```

`[ ]`内のコンテンツはパラグラフやリストなど、なんでも構いません。

`xaringan`のデフォルトテーマに含まれるクラスをもう少し紹介します。

  - `.left-column[ ]`および`.right-column[
    ]`はサイドバーレイアウトの作成に使えます。左のサイドバーはスライドの20%の幅で、右のカラムは75%の幅となっています。
  - `.pull-left[ ]`および`.pull-right[
    ]`は2カラムレイアウトの作成に使えます。2つのカラムは同じ幅で配置されます。

CSSについて知識があれば、自分でコンテンツクラスを定義することもできます。例えば次のようにCSSで定義しておけば、`.red[ ]`でコンテンツ内のテキスト色を赤にすることができます。

``` css
.red{ color: red; }
```

### 3.4 スライドのコンテンツを順次表示する

スライドのコンテンツを順次表示したいような場合は、コンテンツを`--`で区切ります。`--`はコンテンツクラスの内部でなければ、どこでも指定できます。

### 3.5 プレゼンターノート

プレゼンターモード（スライド表示中に`p`を押すと切り替わります）でのみ表示されるノートをスライドに追加することができます。ノートは`???`に続いて記入します。`???`以下の部分でもMarkdownは有効です。つまり、文字の装飾やリスト、画像など、Markdownで記述できるものならなんでも書けます。

スライドに多くの文章を詰め込んでしまう、というのはプレゼンテーションに不慣れな人間が犯しがちなミスです。スライド内の視覚的要素は簡潔に、不足する部分は言葉で補いましょう。もし話す内容を全て覚えていられないというのであれば、ノートの利用を検討してみて下さい。

`remark.js`のプレゼンターモードは非常に強力で、市販のプレゼンテーションソフトのように発表者用の画面と映写用の画面を同期して別々に表示することもできます。そのためには次のように操作します。前提として、PCがプロジェクタに接続されているものとします。

1.  PCとプロジェクタのディスプレイがミラーリングしないように設定する。
  - macOSであれば、「システム環境設定 \> ディスプレイ \>
    配置」で「ディスプレイをミラーリング」のチェックボックスをOFFにします。
2.  スライドをブラウザで表示し、`c`をタイプ。
  - スライドが他のウィンドウ（あるいはタブ）に複製されます。このスライドは複製元のスライドとページが同期します。
3.  複製されたスライドの片方をPCのディスプレイ、もう片方をプロジェクタに移動する。
4.  PC側のスライドをプレゼンターモードにする（`p`をタイプ）
5.  プロジェクタ側のスライドをフルスクリーンにする（`f`をタイプ）

### 3.6 キーボードショートカット

上述のプレゼンターモード切り替え以外にもプレゼンテーションの最中に使えるキーボードショートカットがいくつかあります。キーボードショートカットの一覧は、スライド表示中に`h`（Helpの頭文字）または`?`をタイプすると確認できます。

### 3.7 yoloモード

有効にするとKarl Bromanの画像がランダムにスライドに紛れ込むステキ機能！

画像を好きなものに変更したり、紛れ込み枚数を変更することもできる！

## 4 スライドのビルドとプレビュー

`.Rmd`ファイルを編集する度にknitを繰り返すのは面倒です。アドインの`Infinite Moon Reader`を使うと、`.Rmd`ファイルが更新される度にプレビューも更新されるようになります。アドインを使う代わりに関数`xaringan::inf_mr()`を実行しても構いません。このプレビューは`servr`パッケージにより起動されたローカルWebサーバーにより実現されています。

`xaringan::moon_reader`の出力を他の種類のR Markdownの出力フォーマットと比較した場合の違いとして、デフォルトではself-containedなHTMLが出力されないという点が挙げられます。つまり、画像やJavaScriptライブラリはHTMLファイルに埋め込まれないということです。

これは`remark.js`がPandocを使用せず、Markdownをリアルタイムにレンダリングしているという技術的な理由によります。そのため、self-containedなHTMLを生成するのは困難です。スライドをWebサイトに公開する必要があるが、依存関係のすべてをアップロードすることが難しいという場合には、`xaringan`は良い選択肢では無いかもしれません。GitHub PagesやNetlifyを使う場合はこれは問題になりません。すべてのファイルをコミットするかアップロードすれば良いのです。

## 5 CSSとテーマ

既に説明しましたが、CSSファイルは`css`オプションから指定します。複数のファイルを指定したければパスをベクトルで与えます。

``` yaml
---
output:
  xaringan::moon_reader:
    css: ["default", "extra.css"]
---
```

基本的には、ファイルパスは拡張子を含む必要があります。パスに拡張子が含まれていない場合は、`xaringan`の組み込みCSSだとみなされます。上記の`default`がその例です。これは、パッケージに組み込みの`default.css`を指します。このCSSが保存されている場所は`xaringan:::pkg_resource()`で確認できます。組み込みCSSの一覧は、`xaringan:::list_css()`で確認できます。

デフォルトCSSの一部を変更したいという場合は、`default.css`をコピーするのではなく、新しいCSSファイルを作成してそこで指定するようにしてください。その方が一般的にファイルサイズも小さくできます。

パッケージにはユーザーが投稿したテーマもいくつか含まれています。`metropolis`もその一例です。

``` yaml
---
output:
  xaringan::moon_reader:
    css: [default, metropolis, metropolis-fonts]
---
```

すべてのテーマは`xaringan::list_css()`で取得できる一覧のnames属性を取得することで確認できます。

``` r
names(xaringan:::list_css())
```

    ##  [1] "default-fonts"    "default"          "duke-blue"       
    ##  [4] "hygge-duke"       "hygge"            "metropolis-fonts"
    ##  [7] "metropolis"       "middlebury-fonts" "middlebury"      
    ## [10] "rladies-fonts"    "rladies"          "robot-fonts"     
    ## [13] "robot"            "rutgers-fonts"    "rutgers"         
    ## [16] "tamu-fonts"       "tamu"             "uo-fonts"        
    ## [19] "uo"

テーマにコントリビュートしたい場合は、次のガイドも確認して下さい。

- <https://yihui.name/en/2017/10/xaringan-themes/>

## 6 tips

### 6.1 自動再生

`nature`以下で`autoplay`オプションに時間を指定することで自動再生ができます。指定する時間の単位はミリ秒です。

### 6.2 カウントダウンタイマー

`nature`以下で`countdown`オプションに時間を指定することでカウントダウンタイマーをすべてのスライドに表示できます。時間が来てもスライドは切り替わりませんが、タイマーが赤色になって超過時間を示すようになります。

### 6.3 コードラインのハイライト

`nature`以下で`highlightLines: true`の指定をすると、コードブロック中で`*`から始まる行、`{{ }}`で囲まれた行、`#<<`というコメントがついた行はコードブロック中でハイライトされます。`*`は正しいR構文とはなりませんが、後者2つは追加してもRの構文として特に問題がない、という点にも注目して下さい。

### 6.4 オフラインへの対応

デフォルトでは`xaringan`は`remark.js`のオンライン版を利用します。したがって、スライドをオフラインで使用するつもりであれば、事前に`remark.js`をダウンロードしておく必要があります。`xaringan::summon_remark()`を使用すると、最新版、あるいは任意のバージョンの`remark.js`をダウンロードして保存することができます。デフォルトでは、`libs/remark-latest.min.js`に保存されます。保存したファイルは`chakra`オプションで読み込みの指定をします。

``` yaml
---
output:
  xaringan::moon_reader:
    chakra: libs/remark-latest.min.js
---
```

他の依存関係次第では、スライドを完全にオフライン対応することは難しいかもしれません。`remark.js`自体は単一ファイルから構成されているのでそれほど難しくありませんが、例えばMathJaxは非常にトリッキーです。また、Googleのwebフォントを使用している場合は、これもオフラインでは動作しません。Herokuアプリである[google webfonts helper](https://google-webfonts-helper.herokuapp.com/fonts)はフォントのダウンロードと必要なCSSの生成を助けてくれるでしょう。

### 6.5 マクロ

`remark.js`のMarkdowシンタックスは驚くべき拡張性があります。ユーザー定義のマクロ（JavaScriptの関数です）を定義することができ、`![:macroName arg1, arg2, ...]`や`![:macroName arg1, arg2](this)`のような構文で利用できるのです。例えば、画像の幅をセットする`scale`というマクロを定義してみましょう。

``` javascript
remark.macros.scale = function(w) {
  var url = this;
  return '<img src="' + url + '" style="width: ' + w + '" />';
};
```

このマクロを使うと、次のようなMarkdownが

``` md
![:scale 50%](image.jpg)
```

次のようなHTMLに変換されます。

``` html
<img src="image.jpg" style="width: 50%" />
```

すなわち、よりクリーンな疑似MarkdownからHTMLを生成できる、ということです。

マクロをスライドに組み込むには、まずマクロを適当なjsファイル（例えば`macros.js`）に保存しておき、`nature`以下の`beforeInit`オプションで読み込み指定します。

``` yaml
output:
  xaringan::moon_reader:
    nature:
      beforeInit: "macros.js"
```

このオプションは任意のJavaScriptコードを、`remark.js`がスライドを初期化する前に読み込むのに利用できます。

## 7 `xaringan`の欠点

最後にこのパッケージの欠点について触れておきましょう。

`xaringan`はもともとニンジャのために作られたパッケージです。すなわち、CSSを知っていれば自由にスタイルをカスタマイズできますが、さもなくばデフォルトのテーマを受け入れるしかありません。CSSと戯れることは楽しく実りの多いものですが、時間を簡単に浪費してしまう危険性をはらんでいます。あなたの美的感覚は時間と共に変化するかもしれません。あなたはスタイルの微調整をし続けることになるでしょう。

先に述べたように、`xaringan`のスライドはデフォルトではself-containedではありません。スライドがself-containedでなければならず、サーバーに配置することも望めない場合は、`xaringan`はあまり良い選択肢と言えないでしょう。

HTMLウィジェットは`xaringan`で上手く動作しないことがあります。これは将来的には改善されると思いますが、技術的にはやや難しい問題です。

Google Chromeを使ってスライドのPDFを生成したいと考える場合は、はじめにスライドを一通り表示しておくことをおすすめします。これにより、スライドの内容が確実にレンダリングされます。この作業を行わない場合、MathJaxやHTMLウィジェットなどが正しく表示されない可能性があります。