Slide 1

Slide 1 text

mdbook のプラグインを作る話 Rust LT 会 @puripuri2100 2021/2/25

Slide 2

Slide 2 text

自己紹介 所属 開成学園開成高等学校 学年 高校二年 普段やってること SAT YSFIのパッケージ作成・Rust でのパーサー の作成など twitter @puripuri2100 GitHub @puripuri2100 e-mail [email protected] 1

Slide 3

Slide 3 text

mdbook とは Rust 界隈で大きめの文書を作るときに頻繁に使われるツール (rust-lang 公式がメンテしている) 。 ファイルの path と文章構造を対応させた SUMMARY ファイルを 基に、markdown ファイル群を HTML ファイル群に変換するソフ トウェア。 詳しい使い方は公式ドキュメントの https://rust-lang.github.io/mdBook/index.html を読みましょう。 2

Slide 4

Slide 4 text

mdbook のプラグインについて mdbook-というソフトウェアを用意しておくと、mdbook を 起動したときに自動で実行される。 3

Slide 5

Slide 5 text

mdbook のプラグインについて mdbook-というソフトウェアを用意しておくと、mdbook を 起動したときに自動で実行される。 プラグインにはプリプロセッサと代替バックエンドの 2 種類が ある。 3

Slide 6

Slide 6 text

mdbook のプラグインについて mdbook-というソフトウェアを用意しておくと、mdbook を 起動したときに自動で実行される。 プラグインにはプリプロセッサと代替バックエンドの 2 種類が ある。 book.tomlに書く設定によってどちらで呼び出すのか指定できる。 [preprocessor.]と書くとプリプロセッサを呼び出し、 [output.]と書くと代替バックエンドを呼び出す。 3

Slide 7

Slide 7 text

mdbook のプラグインについて mdbook-というソフトウェアを用意しておくと、mdbook を 起動したときに自動で実行される。 プラグインにはプリプロセッサと代替バックエンドの 2 種類が ある。 book.tomlに書く設定によってどちらで呼び出すのか指定できる。 [preprocessor.]と書くとプリプロセッサを呼び出し、 [output.]と書くと代替バックエンドを呼び出す。 今回自分が作ったのは、 「markdown ファイルから SAT YSFIのド キュメントファイルを生成する」代替バックエンド。 https://github.com/puripuri2100/mdbook-satysfi 3

Slide 8

Slide 8 text

代替バックエンドの作り方 stdinから JSON 形式で設定などが与えられるので、mdbook のラ イブラリの方で提供されている RenderContext::from_jsonという関 数を用いることでデータ構造に自動で直してくれる。 4

Slide 9

Slide 9 text

代替バックエンドの作り方 stdinから JSON 形式で設定などが与えられるので、mdbook のラ イブラリの方で提供されている RenderContext::from_jsonという関 数を用いることでデータ構造に自動で直してくれる。得られる データの種類: • book.tomlに書いてあるものを toml::Value構造にしたもの • 現在位置や生成先の PathBuf • SUMMARY.mdの中の文章構造と、それに対応するファイルの中身 • タイトルや著者名などの book に関するデータ • build 時に使う設定(指定されたファイルが存在しない場合 に自動生成するかしないか、など) • 埋め込む Rust のコードの Edition が何か、という情報 4

Slide 10

Slide 10 text

ハマりどころその 1 基本的には得られるデータを上手いこと弄って変換して出力すれ ば作れるが、ハマったところがあるので紹介 5

Slide 11

Slide 11 text

ハマりどころその 1 基本的には得られるデータを上手いこと弄って変換して出力すれ ば作れるが、ハマったところがあるので紹介 1. markdown ファイルの中身が既に得られている← path を 使ってファイル先を読みにいかなくて良い 5

Slide 12

Slide 12 text

ハマりどころその 1 基本的には得られるデータを上手いこと弄って変換して出力すれ ば作れるが、ハマったところがあるので紹介 1. markdown ファイルの中身が既に得られている← path を 使ってファイル先を読みにいかなくて良い 2. data.book.iter()でファイル構造を iterator にできるので、わ ざわざ再帰関数を書く必要はない 5

Slide 13

Slide 13 text

テキストを出力したい形式に変換する markdown テキストを解析するのには pulldown-cmarkクレートを 用いるのが良い mdbook 本体も使用していて解析結果を統一できるうえに、かな り解析が早く、タグの場合分けによって出力結果を切り変えるの が楽 6

Slide 14

Slide 14 text

ハマりどころその 2 markdown に埋め込まれた HTML コードの解析がとてつもなく 大変 7

Slide 15

Slide 15 text

ハマりどころその 2 markdown に埋め込まれた HTML コードの解析がとてつもなく 大変 基本的に HTML のコードかどうかは「1 行単位」でしか教えてく れない 7

Slide 16

Slide 16 text

ハマりどころその 2 markdown に埋め込まれた HTML コードの解析がとてつもなく 大変 基本的に HTML のコードかどうかは「1 行単位」でしか教えてく れない fuga 7

Slide 17

Slide 17 text

ハマりどころその 2 markdown に埋め込まれた HTML コードの解析がとてつもなく 大変 基本的に HTML のコードかどうかは「1 行単位」でしか教えてく れない fuga コメントの中の HTML タグへの対処や、途中で改行されている HTML タグへの対処などは、正規表現を使って場合分けをしたり、 現在の状態を変化させながら場合分けをしたりする必要があって かなり大変 7

Slide 18

Slide 18 text

ハマりどころその 2(解決策) markdown に埋め込まれた HTML コードごと HTML コードに変換 して、変換後のコードを解析すれば楽になる! 8

Slide 19

Slide 19 text

ハマりどころその 2(解決策) markdown に埋め込まれた HTML コードごと HTML コードに変換 して、変換後のコードを解析すれば楽になる! ただし、&が&になり、<が<に、>が>に自動で変換されて いるので、replaceメソッドを使って置き換える必要がある 8

Slide 20

Slide 20 text

ハマりどころ 3 ソースコード挿入に関して mdbook 独自拡張が存在する1ので、 なんとかしないといけない 1https://rust-lang.github.io/mdBook/format/mdbook.html 9

Slide 21

Slide 21 text

ハマりどころ 3 ソースコード挿入に関して mdbook 独自拡張が存在する1ので、 なんとかしないといけない {{#include file.rs}}のようにすると file.rsを読み込むような拡 張に 関しては、手書きパーサーで頑張りました(力技) 将来的にはここら辺を簡単に処理してくれる関数を公式が提供し てくれると嬉しいですね 1https://rust-lang.github.io/mdBook/format/mdbook.html 9

Slide 22

Slide 22 text

まとめ • book を作るのに良く使う mdbook には拡張機能を自分で作 る機能がある • 公式ライブラリ提供の関数を使えば作成者は変換プロセスだ けに集中できる • ハマりどころがいくつかある • HTML コードへの対処がかなり難しいので、一旦全部 HTML コードに変換するのがオススメ • mdbook の独自拡張については結構頑張る必要がある 10