📈

rustdoc中にp5.jsで図を書く

2023/03/10に公開

数値計算のコードなど、機能の説明に複雑な図を必要とする場合があります。これをp5.jsによって記述する為の簡単なマクロを生成しました。

https://github.com/termoshtt/p5doc

使い方

#[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要素に置き換わります:
image

動作原理

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>要素を追加してそれの下に図を作るように指定することでその位置、この例だとBeforeAfterの間に図を作ってくれます。

これは今回作ったp5docは全く関係なく動作します。なのでもしp5docを使ってみて上手くいかなかったらこの方式に切り替えてください。p5docの手続きマクロはドキュメント中のp5docで始まるインラインコードを見つけてそれを上のような<script>を生成します。ユーザーはdraw()の中身だけを書くだけでドキュメントに図が描画されます。

Roadmap

  • 現在は1つのドキュメントに一つの図しか挿入できません

https://zenn.dev/termoshtt/articles/rustdoc-mermaid-aquamarine
https://zenn.dev/termoshtt/articles/rustdoc-katexit

GitHubで編集を提案

Discussion