タイトルの通りです。以前ここに書いたように,htmlタグ直打ちで実装できたのですが,これでは実用に耐えれません。ということでもっと楽にできるように実装しました。
R Markdownが読み込んでいるもの
R Markdownの基本outputであるhtml_documentには、Bootstrapというデザインワークフレームが組み込まれています。その関係で、jQueryも合わせて読み込まれています。したがって、意図的に除去しない限りはこれら2つは標準で利用可能となっています。
これら2つが使えるということは、Webにおけるいろいろな要素を簡単に組み込むことができます。そこで今回は、BootstrapのPanels機能を,jQueryを利用して実現させてみます。
目標
- htmlタグなし
- 見出し行にBootstrapにあるクラスを付与するだけで実現
- Panelの終点を手動で指定できるようにする
- 部品化して,簡単に他のRmdにも使えるようにする
実装
できました。基本的には以下のようにします:
- スクリプトのみを記述したhtmlファイルを準備
- Rmdファイルを準備
- Rmdのyamlフロントマターに1のhtmlファイルをincludeさせる
- パネルにしたい部分へ{.panel}を付与
めんどくさそうに見えますが,すごく簡単です。
スクリプトのhtmlファイルを準備
これが実装のコアです。以下のようなhtmlファイル(ここではbs_panel.html
)を準備します:
<script>
$(function(){
// .panel要素に,panel-defaultクラスを追加
$(".panel").addClass("panel-default");
// .panel要素をBootstrapのPanel仕様にあわせる
$(".panel").each(function(){
// 見出し要素(h要素)をdivに変換してテキストを保持
// .panel-headingを付与することで,パネルのタイトルにする
$(this).children().eq(0).replaceWith(function(){
$(this).replaceWith("<div class=panel-heading>"+$(this).text()+"</div>");
});
// .panel-bodyの要素となる対象を選択してクラスを付与
$(this).children("*:not('.panel-heading')").wrapAll("<div class=panel-body />");
});
// 手動で終了位置を指定した場合の処理(片付け)
$(".panel-end").each(function(){
$(this).children().eq(0).remove();
$(this).children().unwrap();
});
});
</script>
jsのコーディング規約とか全く知らないので,汚い書き方になってしまいすみません。何をしているかはコード内のコメントを参照してください。このコードをコピペしてファイルを準備してもらえればOKです。
Rmd側の設定
当然ですが,出力はhtml形式で,BootstrapとjQueryが読み込まている必要があります。大抵の場合デフォルトで組み込まれています。
yamlフロントマターの設定
以下のように,先ほどのhtmlファイルを組み込んでください:
---
output:
html_document:
include:
after_body:
- bs_panel.html
---
yamlの書き方については,別途調べてください。
パネル部分の指定
以下のようにすると反応するようになります:
#### パネルの見出し {.panel}
パネルの内部。ほげほげ。
見出しのレベルはどれでもいいのですが,TOCやドキュメントで通常使用するレベルは避けたほうがいいかと思います。これで上記内容がパネルとして出力されます。
ただ,**このままだと「パネルに指定したセクション内容すべてがパネルに収まる」**ことになり,不便です。そこでパネル範囲の終了位置を手動で指定できるようにしてます:
#### パネルの見出し {.panel}
パネルの内部。ほげほげ。
#### {.panel-end}
このように.panel-end
というクラスをつけた空見出し(同一見出しレベル)を差しこめば,そこで閉じるようになります。またこれで生成されてしまう要素(h要素とdiv要素)は除去するようスクリプトに書いてます。
primaryとかwarningとかの指定方法
Bootstrapでの「Contextual alternatives」についても,同じ感覚で使えます。例えば"warning"として使いたいのであれば,以下のようにしてください:
#### パネルの見出し {.panel .panel-warning}
パネルの内部。ほげほげ。
#### {.panel-end}
実践例
このような感じで使えます:
該当スクリプトが記述されたhtmlファイルを読み込むだけなので,プラグイン感覚で利用できます。よかったら使ってください。
Enjoy!