リッチ出力
実行可能セルは複数の typed output artifact を返せます。通常の print や println! も使えますが、より構造化された出力は共通 UI component で表示されます。
出力 type
Section titled “出力 type”Oxiquill は次の出力を表示します。
- stdout、stderr、display output の text。
- 構造化表示される JSON。
- sort 可能な column を持つ table。
- ECharts で render される chart。
- SVG、PNG、JPEG data から作る image。
- iframe 内の sandboxed HTML。
各 artifact は optional string の id、title、caption を持てます。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 を消しません。
Artifact schema
Section titled “Artifact schema”| Kind | Required field | Optional behavior |
|---|---|---|
text | stream: "stdout" | "stderr" | "display", content: string | truncated が bounded content を示します。 |
json | value | cycle-aware formatting が BigInt を明示表現し、truncated が bounded serialized data を示します。 |
table | columns、rectangular rows | rowCount が original size、truncated が preview を示します。 |
chart | 下記の valid spec | oversize/invalid chart は local artifact error。 |
image | mime: image/png | image/jpeg | image/svg+xml、valid data | alt が image alternative。 |
html | html: string, sandboxed: true | empty sandbox、no-referrer、下記の restrictive CSP で表示。 |
table column は key、label、optional type を持ちます。type は string、number、integer、boolean、date、datetime、null、unknown です。各 row は declared column count と正確に一致する必要があります。
Chart schema
Section titled “Chart schema”すべての chart spec は optional title、xLabel、yLabel、xType、yType、legend、tooltip、dataZoom を受け取ります。axis type は value、category、time、log です。未指定 axis は value が default ですが、bar/histogram 固有の axis は category です。heatmap は常に X/Y 両方が category axis であり、xType と yType は省略するか category にできますが、value、time、log は reject されます。
-
valuecoordinate は finite number、logcoordinate は 0 より大きい finite number です。 -
timecoordinate は 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 である必要があります。 -
categorycoordinate は string または finite number です。heatmap axis に明示的なxCategories/yCategoriesarray がある場合、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 は独立して正規化されます。 -
line、scatter、area: optionalnameと[x, y]point を持つseries[]。 -
bar: stringcategories[]と同じ length の numeric-or-nullvalues[]series。 -
histogram:lower < upperかつ count が non-negative の finite[lower, upper, count]tuple のbins[]。 -
heatmap: optional stringxCategories/yCategoriesarray と、二つの 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 | 許可される値と既定値 |
|---|---|
palette | light / dark の少なくとも片方を指定。各テーマに重複しない #RGB / #RRGGBB を1〜12色。heatmap は2色以上。短縮表記を展開し、大文字小文字を区別せず重複判定します。 |
showGrid | boolean。既定値は true。 |
animation | boolean。既定値は true。動作軽減設定を優先します。 |
animationDurationMs | 0〜2,000の整数。初回と更新の既定値は180。 |
lineWidth | 1〜8の有限値。既定値2.25。line / area のみ。 |
symbolSize | 2〜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 にシリアライズし、通常のグラフ検証が同じ制限を適用します。
Resource limit
Section titled “Resource limit”producer は各 language worker 内で postMessage より前に limit を適用し、main thread でも bounded response を独立して再検証します。limit は UTF-8 byte 単位で、記載のものは run ごとに累積します。
| Resource | Limit | 超過時 |
|---|---|---|
| Artifact | 1 run 100個 | 追加 artifact を local reject。 |
| stdout / stderr | stream ごとに 1 MiB | limit までだけ保持し、truncated として表示。 |
| Text、serialized JSON、HTML | artifact ごとに 1 MiB | Text/JSON は truncated: true 可、HTML は reject。 |
| Table | 10,000 row、100 column | bounded table は truncated: true と rowCount を使用可。 |
| Chart | 合計100,000 point/bin/cell | artifact-local error。 |
| Image | decoded 10 MiB | artifact-local error。 |
| 全 validated output | 1 run 16 MiB | remaining budget を超える artifact を local reject。 |
| complete worker response | 16 MiB | worker から page へ渡す前に後続 artifact を省略。 |
| worker error | 16 KiB | UTF-8 message を truncate。 |
| artifact diagnostic | 1件 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 の stdout、stderr、value、plots alias は validated/bounded outputs から再生成され、raw alias が別の unbounded payload を保持することはありません。
CSV copy の安全性
Section titled “CSV copy の安全性”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
Section titled “Python display helper”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
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 output macro
Section titled “Rust output macro”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
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 を解除します。