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

R Markdownでタブ機能の実装

More than 3 years have passed since last update.

この記事の目的

私が大好きなRMarkdownについて、Tipsを集中的に連載しようという思いつきの企画です。あと自分の中で進めている別企画のメモという位置づけでもあります。なので大した中身はありません

R Markdownとは

Markdown記法をベースに、チャンクという形でRのコードを記述して評価・出力することができるものです。RStudioのクイックリファレンスでは以下のように説明してあります:

R Markdown is an easy-to-write plain text format for creating dynamic documents and reports.

R MarkdownにはBootstrapが組み込まれている

色々なところで触れられていますが、R MarkdownにはBootstrapが組み込まれています。具体的にはBootstrap.cssBootstrap.jsが組み込まれていて、各種テーマ・機能が利用可能です1

さてBootstrapの機能については、本家のサイトが一番参考になります:

現在のバージョンは3.3.xで、4がalpha版です。RStudioなどでは主に3.3.xが組み込まれています2。要するにR Markdownで生成したhtmlドキュメントにはこれらの機能が初めから組み込まれているということになるので、使おうと思えばこれら使えるはずなのです。そこで、今回はこの中からタブ機能を実装してみます。出来上がりはこんな感じになります。

Bootstrapのタブ機能の実装(htmlの場合)

Bootstrapのタブ機能を実装するには、以下のようにhtmlを構成します:

<div>

  <!-- ナビゲーションタブ部分 -->
  <ul class="nav nav-tabs" role="tablist">
    <li role="presentation" class="active">
      <a href="#home" aria-controls="home" role="tab" data-toggle="tab">Home</a>
    </li>
    <li role="presentation">
      <a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">Profile</a>
    </li>
  </ul>

  <!-- タブの内容部分 -->
  <div class="tab-content">
    <div role="tabpanel" class="tab-pane active" id="home">...</div>
    <div role="tabpanel" class="tab-pane" id="profile">...</div>
  </div>

</div>

なんかややこしそうです。以下軽く解説します:

ナビゲーションタブ部分

ここは切り替えるためのタブをhtmlで表示するためのものです。基本的な中身はunordered listになります。

まず、<ul>class="nav nav-tabsというクラスを付与します。これはBootstrapのナビゲーションバー(.nav)とナビゲーションタブバー(.nav-tabs)を当てるためです。これでこの中の<li>をタブとしてみなすようになります。

内部の<li>はというと、role="presentation"という属性が当てられています。おそらくJavascriptで色々やろうとするときにきいてくるのだと思います3。また、一つ目の<li>にはclass="active"というクラスが付与されています。これが当たっている項目がアクティブになっている表示となります。なので開いた時に表示させたいタブにこれを付与させるようにします。

そして<a>要素には、href=#homedata-toggle="tab"といった属性が当てられています。前者はタブの内容部分へのリンク先となります。後者はタブ機能を発揮するために必須のもの、と思っておいてください。その他の要素は省略します3

タブの内容部分

ここは切り替えて表示させるタブの内容部分をhtmlで表示するためのものです。divでネストされています。

まず、div class="tab-content"要素は、要するに「このエリアがタブで切り替わるコンテンツだよ」としています。この中にタブで区切るコンテンツを記述します。

そしてdiv role="tabpane1" class="tab-pane active" id="home"の要素ですが、classとして.tab-paneactiveが当たっています。前者のクラスでこのエリアがタブのペインだと指定しています。後者はデフォルト(読み込み時)に表示させるために当てています。そしてid=homeと識別子を付与しています。これが上述のナビゲーションタブ内の<a>の行き先になるので、識別子名をきっちり指定する必要が在ります。

シンプルなタブ切り替えならこれで動くはず

しかし設定項目が多すぎます。色々試してみたのですが、これでいけるようです:

<div>

  <!-- ナビゲーションタブ部分 -->
  <ul class="nav nav-tabs">
    <li class="active">
      <a href="#home" data-toggle="tab">Home</a>
    </li>
    <li>
      <a href="#profile" data-toggle="tab">Profile</a>
    </li>
  </ul>

  <!-- タブの内容部分 -->
  <div class="tab-content">
    <div class="tab-pane active" id="home">...</div>
    <div class="tab-pane" id="profile">...</div>
  </div>

</div>

つまり必要なのは各要素のclass属性とid属性、そして`data-toggle="tab"という属性です。これがあれば、シンプルなタブ切り替えは機能しました。

R Markdownでタブ機能の実装

結論から言うと、こんな感じで実装できました。

追記(2016/01/22): <a>タグの行のインデントを減らしました。設定によってはうまく動作しないためです。4

(省略)

# {.tab-content}

<ul class="nav nav-tabs">
  <li class="active">
  <a href="#tab1" data-toggle="tab">tab1</a>
  </li>
  <li role="presentation">
  <a href="#tab2" data-toggle="tab">tab2</a>
  </li>
</ul>

## tab1 {#tab1 .tab-pane .active}
hogehoge. hogehoge.


## tab2 {#tab2 .tab-pane}
wasshoi! wasshoi!

まず、R MarkdownはPandoc Markdownなので、見出しの行末に{}を与えると、classなどの属性を付与できるようになっています。またデフォルトの設定でこの見出しより下位レベルの要素を括るように、div要素でまとめられます。これを利用します。

まずタブペインを構成する部分について、id属性と.tab-paneクラスを付与します。これでこの部分はタブの内容として扱われます。ただ、このままだとdiv.tab-contentでまとめることができません。そこで、中身が空っぽの見出し1レベルを用意し、そこに.tab-contentを設定しました5。別に中身が空っぽである必要はなく、タイトルになるようなものがあれば、それを書き込んでください。

なお、ナビゲーションタブ部分についてはMarkdownだけで表現するのは厳しかったので、html直打ちしました。この部分は、今回# {.tab-content}の内側にありますが、この外に置いていてもOKです。また、2つ以上のタブが必要であれば、順次<li>など追加してください。

注意事項(2016/01/22追記)

こちらの記事で紹介している「目次と見出しの通し番号の自動挿入」との併用は避けたほうがいいでしょう。今回Rmdでタブのエリアを指定するために、空のh1要素を使っています。これをきっちり拾ってしまうためです。

もし両立させようとするのであれば、<div>タグをhtml手打ちすることになりますが、場合によってはうまく行かないかも知れません。もっとも、タブ構成にしているので目次作ったり通し番号を有効にするメリットはあまりないと思いますが…。

Enjoy!


  1. 正確にはそれ以外の書式なども組み込まれているため、たまに打ち消されてしまっているのもあります。 

  2. 私の手元での環境です。極端に古いRStudioや{rmarkdown}を利用している場合は違うかも知れません。 

  3. 詳しくはBootstrap公式ドキュメントをご覧ください。私にはよくわかりません。 

  4. Markdownの記法によっては、行頭に4つスペースがあるとその行はコードブロックと判断します。RStudioの設定でタブをスペースとしていたり、Pandocに投げるオプションによってはタブの見出しにhtmlがコードとして表示されます。 

  5. 今回は###を利用しましたが、別に#####であっても構いません。 

Why do not you register as a user and use Qiita more conveniently?
  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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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