R MarkdownでWord文書を作って
同人誌作った話とその先

niszet

2019/5/20

R MarkdownでWord文書を作って同人誌作った話

誰?

なまえ:niszet
ぞくせい:Rおじさん 兼 回路設計miscおじさん
すてーと:4月末退職して次のステージへ

self

タイトル is どういうこと?

  • R界隈で活動したい。

  • でも、分析とかやってないのでなんもわからん

  • R Markdownはわかる…けど

  • Word形式へ出力する情報が全然見つからない

  • ないので書いた

Word本について

hyoshi

  • 技術書典5で初頒布。累計140?部くらい出ている。

    • でもまだ在庫あるよ
  • R Markdownで書いてWordに変換してpdfにして入稿。

    • R Markdownでも同人誌が作れる!
  • 気づいたら1か月くらいで80ページになっていた不思議

R/R Markdownとは?

“R” Markdown?

  • R言語で文書作成する際のデファクトスタンダード。

    • R言語は主に統計方面に強く、R Markdownを使ってデータの処理自体も一体化することで結果の再現性に有効。
  • 後段でPandocを使用することを前提として、
    R言語で書かれた処理の結果(図や表など)を含んだMarkdownが作成できる。

  • 文書形式の変換はPandocが担当するため、基本的にはPandoc’s Markdownで書く必要がある。

  • コードはブロック形式、インライン形式それぞれで記述可能。用途に合わせて使用する。

R Markdownに関する書籍など

和書が比較的充実している。ネット上に情報も多い。

他にも検索すれば沢山情報が手に入る(はず)

R言語はいいぞ…

  • R 言語は統計関係のライブラリが多く、可視化や前処理、ドキュメント化にも強い。

  • R MarkdownはRだけでなく、PythonやJuliaなどの言語の実行結果を使うことも可能。

R Markdown 環境作成編

環境を揃える苦しみ

  • 以下ではWindows上で使用することを想定しています。

    • そもそもMacでOfficeはツライ(らしい)

    • R自体はMac/Linuxでも使用可能だし、docxファイルの作成自体はLinux上でも可能。

  • R, RStudio, RTools, Windows, Pandoc, Wordのそれぞれのバージョンが揃っていないと完全再現できない(と思う)

    • 実際に新しいPandocのバージョンで作成したPowerPointのテンプレートが古いPandoc側で使用できないなどの問題はあった。

    • WindowsやWordはOffice365だと勝手に更新されるのでバージョンを保つのは困難(今のところこれが問題となったことはないけど)

  • Setup自体はかなり簡単なので、導入はしやすい。

  • Q. Docker使えばいいんじゃないですかね…?

    • A. そうですね。でも…ちょっとした気持ちで文章・文書を書きたいだけなのに、それって本末転倒では…?

R/RStudio IDEの導入

RStudio中のPandoc環境について

Pandocは同梱されているが、少し古い場合がある(Pandocの更新が速すぎるという説)

Pandocのバージョンを変えたい場合は、上のコマンドで確認したファイルパスにある実行ファイルを所望のバージョンのPandocで上書きする。上書き後、RStudioは念のため再起動する。

R Markdownで文書作成の流れ

  • R MarkdownからMarkdownへの変換をRのパッケージで対応している。

    • knitrrmarkdown パッケージでhtml, word, pdfなどに対応
  • 出力形式毎にパッケージが存在する

    • GitBook形式などの bookdown

    • CSS組版の pagedown

    • HTMLスライドの revealjs

    • などなど…

  • どの形式でもMarkdownファイルに変換後はPandocで変換処理をするので、Pandocの知識はある程度のレベル以上から必須となる(はず)

結局のところ、R Markdownとは…?

  • R Markdownはプログラムを埋め込むことが出来るMarkdownだと思えばよく、Markdownの生成を自動化したり条件によって処理を変えるなどといったことが可能。

  • 肝心のフォーマット変換はPandocが行うので、Pandocに出来ないことはR Markdownでも基本的には“出来ない”。

  • 生成後のファイルをRを使って直接修正する方法もあるけど…

    • officer パッケージなど

Pandocのはなし

Pandocをよりよく知るために手を付ける順番

  1. とりあえずMarkdownを書いてファイルを変換、動かしてみる

  2. 設定を変更して出力ファイルを見て判断

  3. Pandoc native形式とLua filterに手を出す(他の言語のFilterでも良い)

  4. Reader/Writerに手を出す(Haskell…)

Markdownの文法

  • Pandocのマニュアル(User’s Guide)を読むか、R Markdownのマニュアルが便利(最低限がまとまっているので)

    • 段落内改行が行末に半角空白2つかバックスラッシュ\かみたいな細かい話はPandoc User’s Guideを読まないとわからない。
  • Markdown全般について知るなら、書籍はコレでしょ!

Users Guideは読もう。

何度読んでも何度も忘れるので何度も読み直す必要がある…。

ただし、書いてあることとちょっと挙動が異なるような…?みたいなことはある(が、各種環境の違いで再現しないことが多々あるのでなんとも…)

ちょっとわかりにくいよね…って部分があるので自分で書いてみないとわからない部分多々あり。

Pandocのオプションはデフォルトで有効なのか無効なのか問題

  • Markdown extensionsのうち、デフォルトで有効なものとそうではないものがある。これはマニュアルには明記されていない

    • あったら教えてください…

    • たぶんこれもコード読む必要がある…

  • Word本でも主要なものは明記したが、使用頻度が低そうなものは除いた。HTML出力の場合などもまた別にあるので…

Pandocについてまとめ

  • とりあえず使ってみよう。

  • 自分が良く使う設定や文法は一通りテンプレートにしてコピペしておくのが一番…

  • 設定は好みがあるので、どれがベストかは…??

  • わかってる人に聞くのが一番

    • どうすればよい?

Word形式の話

Word文書を作成する

  • 世の中にはドキュメントはWord形式で欲しいと言ってくる層が一定数いる。

    • 分析界隈でもそうらしい…。

      • JTC…?当然ですね…。

        • でもそもそも自由にRとかインストールできないよね…ツライ
  • 書いたときは絶対需要ないと思ったのにそれなりにウケてるのが不思議…。

Wordはスタイルを使いましょう…

  • Wordで直接書く場合も段落や文字に対して見栄えを定義したスタイルを使って書いた方が良い

    • …のだが、人間のやることなのでミスが多い。スタイルを設定しない人は沢山いる。
  • PandocでWordに変換する場合、文章の構成要素それぞれにWordのスタイルが割り振られる。

  • Wordはスタイル毎に見た目の設定が出来るので、対応関係がわかっていればMarkdownを書くだけでいい感じの見た目のWordドキュメントが作れる。

    • …んだけど、このスタイルの設定がとても鬼門。難しい。まとめたい・・・

Template

  • Pandocで生成する文書の見栄えを決めるのはテンプレート。

  • Wordの場合は--reference-docで指定する。

  • Word自体は結構高機能なので、大体のことが出来る。ヘッダーフッターも設定しておけば有効。

    • ロゴいれたり、ページ番号いれたり、パラメータをいれたり
  • スタイルの設定が大変だが、一度テンプレートファイルを作成すれば使いまわしがきくので時間をかける価値はある。

スタイルの対応表が欲しい…。

  • ない。

    • ないので作った。
  • 実は昔書いている。未だにアクセス数がとても多い謎。

  • Pandocを使う以上はMarkdownの各Block, Inline要素がどのスタイルに割り当てられるのか?は共通なので、MPEでも同じ。

スタイル目視確認のツラミ

  • どのようにスタイルが割り当てられているかは、PandocのWriterのコードを読めば多分わかるはず。

  • しかし、当時は(今も)Haskellの解読がniszetにはちょっと厳しかったので、結局、書いて変換して確認する…を繰り返し実行した(ツライが確実)

Custom Styleもつかおう

  • Wordの場合はStyleでかなりの部分が対応できる。
    https://pandoc.org/MANUAL.html#custom-styles

  • 特にCustom Styleを使えれば、任意のStyleを割り当てられるので便利

    • 見出し1に改行を入れるといったことも可能(#を使うと改行入れられない)

    • これをRの関数で表現すれば本文が見づらくなることもない(はず)

Wordのはなしのまとめ

  • スタイルを設定したテンプレートを使おう

  • Markdownから作ればWordから直接書くよりもスタイルを有効に利用できる。

  • スタイルの設定は面倒…

OOXML(Office Open XML)の話

docxはzipされたxml

  • 拡張子がdocxのWord文書のファイルはzipされたxmlファイル。

  • PandocにはGeneric raw attributeがあるので、これを使って出力先の形式のコードを直接埋め込むことが出来る。

  • Wordの場合はOffice Open XMLで書かれたコードをそのまま埋め込むことが可能。

OOXML使う例

  • Markdownにはページの概念がない(HTMLにもないけどネ)

  • Wordで出力する場合は「丁度良い場所で改ページしたい」ことがある

  • 公式のマニュアルにも改ページの例が載っている

  • 任意のOOXMLを埋め込むことが出来るが、 一番外側は<w:p>タグで囲う形にすること。

  • document.xmlに含まれる内容のみ対応できる。他のファイルに影響を与えるようなものはダメ。

文書中に直接OOXMLを直接書くのはちょっとツライ

  • 文章中にコードを埋め込むと、文章としての可読性はかなり落ちる(ブロックなら折りたたむなども出来るが)

  • Rの関数化、パッケージ化することで、見づらいOOXMLのブロックが文書中に散りばめられることがなくなる。

    • インラインにRのコードが書けるのでOOXMLのコードブロックを文字列として返す関数を定義すればよい。“R” Markdownを使う強みの1つ。

      • ブロックのRのコードだとうまくいかないと思う。
    • 出来るだけ文章書くことに専念できるようにパッケージ化して「おまじない」にしたい

Wordは機能が多すぎる…

  • OOXMLを使うことで、Markdownで表現できないWordの機能を使うことが可能

  • しかしWordは機能が多すぎる&OOXMLの解読がとても大変なので、Styleの使いこなしができてからでよいと思います。

今後のおはなし。

次のステップ

  • R側で出来ることは多いが、Pandocの仕様的に逃げられない部分はPandoc側で何とかしたい。

    • Writer起因の動作は特にそう。しかし、Reader/Writerに手を出したくない。
  • Lua filterを使えば良さそう。Writerの処理を迂回することができる。

Pandoc Nativeの話

  • Lua filterはnative形式のデータ構造に対して変換処理をかけるので、nativeデータ構造の理解は大事。

  • PandocはReaderでファイルを読み、一旦Pandoc Native形式に変換してそれをWriterで所望の形式に変換している。

  • -t nativeを指定すればNative形式で出力することも可能。

  • 意図した変換結果が得られなかった場合、一旦nativeで出力するのはアリ。

  • 中身はASTなのでそんなに難しくはない(諸説あります)

Lua filterの話

  • PandocはLuaで書かれたFilterが使える。

    • PandocのReader/Writerの挙動は変更せず、解釈されたASTに対して処理を加えることが出来る。
  • Lua Filterは環境に依存しない(LuaがPandocに含まれている)ため移植性が高い。Luaもバージョン5.3なので最新(?)環境が使える。

  • PandocのASTを変換するので、Writerで処理しているものには対応できない。

    • 他の言語でもJSONを取り扱えるなら問題なく使えるらしいが環境を揃えるのが大変になるので、Lua Filterを使う方が移植性としてはベター
  • これも公式の説明やLua filterのリポジトリがあるのでそれを参考にするのがよさそう。

Lua filterを使うためには…

Luaのお勉強

  • Programming in Lua の Fourth edition がLua5.3の情報も載っていて(むしろ5.3の話がメイン)良い。翻訳版はまだなさそう。

  • Lua5.xでも基本的な文法はほぼ問題ないので、Webにある日本語で書かれたサイトから入門する方が良さそう。

  • リファレンスマニュアルは日本語訳されている。

  • tableまでの話と関数の書き方がわかれば「とりあえず動かすレベル」は出来る

具体例:スタイルの割り当てを変える。

  • 脚注や見出しにCodeが入る場合、Source CodeのスタイルがCodeに当てられてしまうため、周囲の文字列とフォントやフォントサイズが違い、見た目がおかしくなる。

same_style

コード例

下記のように簡単(?)に実現できる。

ちょっとだけ説明。

  • function Header (elem) ... end でHeader要素に対して処理が出来る。

    • Metaなどにも対応できる。
  • 戻り値はpandoc.要素で返すと良いが文字列でも良さそう。

  • Luaは比較的型に寛容だがPandoc(Haskell)は厳しいのでnumericを返すとエラーになるので注意。

  • 自身の子要素でCodeがあったらSpanを使ってカスタムスタイルをあてている。

スタイルの話、補足。

  • Wordのスタイルは段落と文字の2種類がある(PandocのBlockとInlineに相当する)

  • そのため、Word形式で出力する場合、スタイルの割り当てで対応するスタイルがないとうまくスタイルをあてられない。

PowerPointをつくる

本も書いた…が、現状では制約が多くて厳しい…。

おわりに

まとめ

  • R MarkdownでWordを作るのは全然いける

  • まだもうちょっと頑張りどころがある

  • ここでは紹介しきれなかった細かいツラミがある…

  • しかし、R/Markdown/YAML/Lua/Haskell/OOXML … と押さえないといけないもの多すぎじゃないですかね…

Enjoy!!

self