rustdoc中にp5.jsで図を書く
数値計算のコードなど、機能の説明に複雑な図を必要とする場合があります。これをp5.jsによって記述する為の簡単なマクロを生成しました。
使い方
#[cfg_attr(doc, p5doc::p5doc)]
/// Some function!
///
/// Before
///
/// ```p5doc:200x100
/// background(220);
/// ellipse(50,50,80,80);
/// ```
///
/// After
///
pub fn some() {}
このように記述するとp5doc
の部分がp5.jsでによって描画されたHTMLのCanvas要素に置き換わります:
動作原理
Rustのドキュメントジェネレータrustdoc
はMarkdown形式で記述された内容からHTMLのドキュメントを生成しますが、この際HTML片はそのまま受理されて出力のHTMLに埋め込まれます。これは<script>
を埋め込んでもいいので、例えば:
/// Head line
///
/// <script>alert("Hey!")</script>
pub fn test() {}
と記述するとこのtest()
のページを開くとalert
が発生します。これはrustdoc
を実行したときではなく、ドキュメントをブラウザが開いたときにこの<script>
を見て実行している事に注意してください。つまり任意のJavaScriptライブラリをドキュメントを書くために使えます。これを応用して、図を生成するのに必要なJavaScriptのスクリプトをドキュメント内に埋め込んでおき、ユーザーがブラウザでそのドキュメントを開いたときにブラウザに図を描画させることが出来ます。
そこで図を描画してくれるJavaScriptのライブラリが必要になります。今回はp5.jsを選択しました。p5.jsは電子アートとビジュアルデザインを標榜するProcessingの開発元が作っているJavaScriptライブラリで、同じように図を書いたりアニメーションを作ったりできます。
p5.jsをCDNから取得して簡単な図を書くドキュメントを生成するには例えば次のように書きます:
/// Some function!
///
/// Before
///
/// <script src="https://cdn.jsdelivr.net/npm/p5@1.6.0/lib/p5.js"></script>
/// <script>
/// function setup() {
/// var canvas = createCanvas(200, 200);
/// canvas.parent("doc-some");
/// }
/// function draw() {
/// background(220);
/// ellipse(50,50,80,80);
/// }
/// </script>
/// <div id="doc-some"></div>
///
/// After
///
pub fn some() {}
p5.jsは2つの関数setup()
とdraw()
を定義するとそれに従って図を書いてくれます。setup()
の中のcreateCanvas(200, 200)
でHTMLの<canvas>
要素がページに作られ、ellipse(...)
で楕円が追加されます。この時何もしていしないとページの一番下に図を作ってしまうので<div>
要素を追加してそれの下に図を作るように指定することでその位置、この例だとBefore
とAfter
の間に図を作ってくれます。
これは今回作ったp5doc
は全く関係なく動作します。なのでもしp5doc
を使ってみて上手くいかなかったらこの方式に切り替えてください。p5doc
の手続きマクロはドキュメント中のp5doc
で始まるインラインコードを見つけてそれを上のような<script>
を生成します。ユーザーはdraw()
の中身だけを書くだけでドキュメントに図が描画されます。
Roadmap
- 現在は1つのドキュメントに一つの図しか挿入できません
- Issueは立ててありますが、複数の図を書く場合Globalモードでなくinstanceモードを使う必要があるので何かしらの変換機構をつくるか、ユーザーに常にinstanceモードで書かせることにするか、設計の選択があるので一旦放置です。
Links
Discussion