コンテンツにスキップ

リッチ出力

実行可能セルは複数の typed output artifact を返せます。通常の printprintln! も使えますが、より構造化された出力は共通 UI component で表示されます。

Oxiquill は次の出力を表示します。

  • stdout、stderr、display output の text。
  • 構造化表示される JSON。
  • sort 可能な column を持つ table。
  • ECharts で render される chart。
  • SVG、PNG、JPEG data から作る image。
  • iframe 内の sandboxed HTML。

各 artifact は optional string の idtitlecaption を持てます。worker から受け取る value は untrusted です。Oxiquill は renderer に渡す前に discriminator、field、plain-record structure、array shape、finite number、row width、MIME/base64 data、nested value を検証します。reject/render failure になった一つの artifact は local diagnostic を表示し、valid sibling を消しません。

KindRequired fieldOptional behavior
textstream: "stdout" | "stderr" | "display", content: stringtruncated が bounded content を示します。
jsonvaluecycle-aware formatting が BigInt を明示表現し、truncated が bounded serialized data を示します。
tablecolumns、rectangular rowsrowCount が original size、truncated が preview を示します。
chart下記の valid specoversize/invalid chart は local artifact error。
imagemime: image/png | image/jpeg | image/svg+xml、valid dataalt が image alternative。
htmlhtml: string, sandboxed: trueempty sandbox、no-referrer、下記の restrictive CSP で表示。

table column は keylabel、optional type を持ちます。type は stringnumberintegerbooleandatedatetimenullunknown です。各 row は declared column count と正確に一致する必要があります。

すべての chart spec は optional titlexLabelyLabelxTypeyTypelegendtooltipdataZoom を受け取ります。axis type は valuecategorytimelog です。未指定 axis は value が default ですが、bar/histogram 固有の axis は category です。heatmap は常に X/Y 両方が category axis であり、xTypeyType は省略するか category にできますが、valuetimelog は reject されます。

  • value coordinate は finite number、log coordinate は 0 より大きい finite number です。

  • time coordinate は finite epoch millisecond、または YYYY-MM-DDTHH:mm:ss[.sss]Z / YYYY-MM-DDTHH:mm:ss[.sss]±HH:mm 形式の ISO-8601 string です。calendar field と明示的な time zone も valid である必要があります。

  • category coordinate は string または finite number です。heatmap axis に明示的な xCategories / yCategories array がある場合、coordinate は完全一致する listed string、または範囲内の safe な zero-based integer index に限定されます。index はその位置の category name に解決され、数値らしい新しい category name には変換されません。

  • heatmap axis に明示的な categories array がない場合、finite number と string は String(coordinate) で正規化され、category は初出順に推論されます。1"1" のように同じ label に正規化される値は一つの category を共有します。片方の axis だけ categories を宣言した場合も、X と Y は独立して正規化されます。

  • linescatterarea: optional name[x, y] point を持つ series[]

  • bar: string categories[] と同じ length の numeric-or-null values[] series。

  • histogram: lower < upper かつ count が non-negative の finite [lower, upper, count] tuple の bins[]

  • heatmap: optional string xCategories/yCategories array と、二つの category axis 上の finite [x, y, value] cell。

empty chart と equal point domain は valid です。heatmap は X/Y の category 数と heat value の範囲を示し、color scale には実際の heat value を使います。empty dataset だけは 0–1 を fallback にします。chart は textual title/caption と bounded accessible summary または equivalent table を提供します。equivalent がある場合、implementation canvas は accessibility API から隠されます。

chart は現在の Starlight light/dark theme に合わせた contrast-aware color を使い、html[data-theme] の変更時に ECharts instance を作り直します。一時的な renderer load failure の後には retry action を表示します。

出力の保持とグラフのスタイル

Section titled “出力の保持とグラフのスタイル”

セルを再実行している間も、最後に成功した出力を表示し続けます。150ms の reactive debounce 中も同様です。更新中の表示はレイアウトを動かしません。再実行が失敗した場合は出力とエラーを併記し、セルの実行を再試行からやり直せます。キャンセルや入力不正でも出力を保持し、成功時に結果を置き換えてエラーを消します。出力の並びが動的に変わる場合は artifact に明示的な id を付けてください。重複 ID は出現番号で区別し、ID のない artifact は種類ごとの出現番号で対応付けます。

互換性のあるグラフは既存の canvas と ECharts instance を更新し、読者のズーム範囲を保持します。初回とデータ更新のアニメーションは既定で180ms、easing は cubicOut です。構造変更時は同じ instance の設定を置き換え、Starlight の light/dark 変更時には instance を作り直します。グラフ更新が失敗しても最後の表示と概要を残し、局所的な再試行操作を表示します。OS の動作軽減設定は著者の animation 指定より優先され、グラフと更新表示のアニメーションを無効にします。

chart spec は次の optional style object を受け取ります。

interface ChartPalette {
light?: readonly string[];
dark?: readonly string[];
}
interface BaseChartStyle {
palette?: ChartPalette;
showGrid?: boolean;
animation?: boolean;
animationDurationMs?: number;
}
interface LineChartStyle extends BaseChartStyle {
lineWidth?: number;
}
interface ScatterChartStyle extends BaseChartStyle {
symbolSize?: number;
}

line と area は LineChartStyle、scatter は ScatterChartStyle、bar・histogram・heatmap は BaseChartStyle を使います。

Field許可される値と既定値
palettelight / dark の少なくとも片方を指定。各テーマに重複しない #RGB / #RRGGBB を1〜12色。heatmap は2色以上。短縮表記を展開し、大文字小文字を区別せず重複判定します。
showGridboolean。既定値は true
animationboolean。既定値は true。動作軽減設定を優先します。
animationDurationMs0〜2,000の整数。初回と更新の既定値は180。
lineWidth1〜8の有限値。既定値2.25。line / area のみ。
symbolSize2〜32の有限値。既定値7。scatter のみ。

palette は系列色を選び、heatmap では visual-map のグラデーションになります。片方のテーマが未指定なら、そのテーマの Oxiquill 既定色を使います。文字やグラフ周辺の色は Starlight に従います。不明な nested field、別の種類専用の field、生の ECharts options、callback、formatter、HTML は拒否します。style も通常の artifact byte 制限に含まれます。

既存の Rust macro signature はすべて利用できます。次の overload では末尾に JSON-serializable な style(例: &serde_json::json!({ "lineWidth": 3 }))を追加できます。

emit_line_chart!(series, style)
emit_line_chart!(series, x_label, y_label, style)
emit_scatter_chart!(series, style)
emit_scatter_chart!(series, x_label, y_label, style)
emit_bar_chart!(categories, values, style)
emit_histogram!(bins, style)
emit_heatmap!(data, style)
emit_line_plot!(points, x_label, y_label, style)

macro は spec.style にシリアライズし、通常のグラフ検証が同じ制限を適用します。

producer は各 language worker 内で postMessage より前に limit を適用し、main thread でも bounded response を独立して再検証します。limit は UTF-8 byte 単位で、記載のものは run ごとに累積します。

ResourceLimit超過時
Artifact1 run 100個追加 artifact を local reject。
stdout / stderrstream ごとに 1 MiBlimit までだけ保持し、truncated として表示。
Text、serialized JSON、HTMLartifact ごとに 1 MiBText/JSON は truncated: true 可、HTML は reject。
Table10,000 row、100 columnbounded table は truncated: truerowCount を使用可。
Chart合計100,000 point/bin/cellartifact-local error。
Imagedecoded 10 MiBartifact-local error。
全 validated output1 run 16 MiBremaining budget を超える artifact を local reject。
complete worker response16 MiBworker から page へ渡す前に後続 artifact を省略。
worker error16 KiBUTF-8 message を truncate。
artifact diagnostic1件 8 KiB、1 run 64 KiB各 limit 内で diagnostic を truncate。

truncated: true を使えるのは text、JSON、table だけです。chart、image、HTML は黙って truncate しません。invalid/cyclic/over-deep JSON、ragged table、non-finite chart value、invalid base64/MIME pair、unsafe structural record が cell component を crash させることはありません。legacy の stdoutstderrvalueplots alias は validated/bounded outputs から再生成され、raw alias が別の unbounded payload を保持することはありません。

default table action は表示中の row を spreadsheet-safe CSV として copy します。最初の meaningful character が =+-@、tab、carriage return の string header/cell には、RFC-style の comma/quote/line-break escape より前に apostrophe を付けます。この決定的な規則により、一般的な spreadsheet application が string data を formula として評価することを防ぎます。数値は変更しないため、実際の number -42-42 のままです。

Python セルには display helper が含まれます。

  • display(value) は value から JSON、table、image、HTML、text の出力を選びます。
  • display_json(value) は JSON を出力します。
  • display_html(html) は sandboxed HTML を出力します。
  • display_table(rows_or_dataframe) は table を出力します。
  • display_image(data, mime) は SVG、PNG、JPEG image data を出力します。

runtime は pandas DataFrame/Series、matplotlib figure、_repr_mimebundle__repr_json__repr_html__repr_svg__repr_png__repr_jpeg_ などの rich representation も扱います。

Python + Pyodide

Python table, matplotlib, HTML, and JSON outputs

Cell actions
import pandas as pd
import matplotlib.pyplot as plt

scores = pd.DataFrame({"label": ["alpha", "beta", "gamma"], "score": [3, 5, 4]})

display(scores, title="Pandas table")
display_json({"status": "ok", "rows": len(scores)}, title="Summary")
display_html("<p><strong>Sandboxed HTML</strong> emitted from Python.</p>", title="HTML")

plt.bar(scores["label"], scores["score"])
_ = plt.title("Scores")
_ = plt.xlabel("label")
_ = plt.ylabel("score")

Run the cell to show its output.

Rust セルでは明示的な emit_* macro を使います。対応 macro:

  • emit_text!
  • emit_json!
  • emit_html!
  • emit_svg!emit_image_svg!
  • emit_png_base64!emit_image_png!
  • emit_table!emit_table_with_columns!emit_records_table!
  • emit_line_chart!emit_scatter_chart!emit_bar_chart!emit_histogram!emit_heatmap!
  • 互換用の emit_line_plot!

Rust + Wasm

Rust table, chart, JSON, SVG, and HTML outputs

Cell actions
let rows = vec![
    serde_json::json!({"label": "alpha", "score": 3}),
    serde_json::json!({"label": "beta", "score": 5}),
    serde_json::json!({"label": "gamma", "score": 4}),
];
let columns = vec![
    serde_json::json!({"key": "label", "label": "Label", "type": "string"}),
    serde_json::json!({"key": "score", "label": "Score", "type": "integer"}),
];
let heatmap = [[0, 0, 1], [1, 0, 3], [0, 1, 2], [1, 1, 4]];

emit_json!(&serde_json::json!({"status": "ok", "rows": rows.len()}));
emit_records_table!(&rows);
emit_table_with_columns!(&columns, &rows);
emit_bar_chart!(&["alpha", "beta", "gamma"], &[3, 5, 4], &serde_json::json!({
    "palette": { "light": ["#7c3aed"], "dark": ["#c4b5fd"] },
    "animationDurationMs": 180
}));
emit_heatmap!(&heatmap);
emit_svg!(
    r##"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 48"><rect width="160" height="48" fill="#ecfeff"/><circle cx="32" cy="24" r="14" fill="#0f766e"/><rect x="64" y="12" width="72" height="24" rx="4" fill="#2563eb"/></svg>"##,
    "Simple generated SVG"
);
emit_html!(r#"<p><strong>Sandboxed HTML</strong> emitted from Rust.</p>"#);

Run the cell to show its output.

短い説明文には stdout を使います。正確な構造を見せたい場合は JSON、比較可能な record には table、傾向や分布には chart、生成された視覚情報には image、他の artifact で表せない markup には sandboxed HTML を使います。

copy、sort、pagination、validation、running、completion、failure state は keyboard 操作可能で、localized English/Japanese label とともに announce されます。sandboxed HTML には意図的に script/same-origin permission がなく、referrer を送らず、external subresource を default で block します。正確な policy と trust boundary は サポートとセキュリティ を参照してください。

table interaction state は一つの execution result に限定されます。新しい result では page、sort、copy status を reset します。同じ result の rerender は互換性のある sort/page を維持しますが、row が減った場合は clamp 後の page を保存し、sort 対象 column が削除・置換された場合は sort を解除します。