# P5 Magic Command
## 概要
Jypyter(notebook/lab)・VSCodeまたはGoogle Colabでp5.js/q5.js/p5play.jsを使ったコードセルのPythonコードをPyScriptを使ってiframe(ブラウザ)上で実行するマジックコマンドです。
## 使い方
### マジックコマンドの追加
コードセルに以下のコードを貼り付けて実行しマジックコマンドを登録してください。カーネルやランタイムを再起動する度に再実行する必要があります。
```python
%pip install -q -U pysmagic p5magic
from p5magic import register_p5magic
register_p5magic()
```
### マジックコマンドの使い方
コードセルの冒頭に以下のようにマジックコマンドを記述してください。実行するとアウトプットにiframeが表示されてその中でコードセルのコードがPyScriptで実行されます。グローバルモード及びインスタンスモードの両方に対応しています。
以下は、q5.jsライブラリを使って描画した赤い円を矢印キーで動かす例です。
#### グローバルモード
```python
%%runp5
x = 100
y = 100
def setup():
p5.createCanvas(300, 300)
def draw():
global x, y
background(128)
fill(255, 0, 0)
ellipse(x, y, 50, 50)
if keyIsDown(LEFT_ARROW):
x -= 1
if keyIsDown(RIGHT_ARROW):
x += 1
if keyIsDown(UP_ARROW):
y -= 1
if keyIsDown(DOWN_ARROW):
y += 1
```
#### インスタンスモード
```python
%%runp5 500 500 white '{}' False
import pyscript
import js
def sketch(p5):
x = 100
y = 100
def setup():
p5.createCanvas(300, 300)
def draw():
nonlocal x, y
p5.background(128)
p5.fill(255, 0, 0)
p5.ellipse(x, y, 50, 50)
if p5.keyIsDown(p5.LEFT_ARROW):
x -= 1
if p5.keyIsDown(p5.RIGHT_ARROW):
x += 1
if p5.keyIsDown(p5.UP_ARROW):
y -= 1
if p5.keyIsDown(p5.DOWN_ARROW):
y += 1
p5.setup = setup
p5.draw = draw
js.p5start(sketch)
```
### グローバル変数
PyScriptから以下の変数にアクセスできます。
- 別のセルで設定したグローバル変数(_で始まる変数名やJSONに変換できないものは除く)
- マジックコマンドの引数py_valで設定した変数
- width: iframeの幅(マジックコマンドの引数で指定した幅)
- height: iframeの高さ(マジックコマンドの引数で指定した高さ)
この変数はjs.pysオブジェクトを介してアクセスできます。
変数名が衝突した場合は上記リストの順に上書きされて適用されます。
### マジックコマンド
#### %%runp5
セル内のp5play.jsライブラリを使ったPythonコードをPyScriptを用いてiframe内で実行するマジックコマンド
```juypyter
%%runp5 [width] [height] [background] [py_val] [p5_global] [p5_type] [p5play_use] [py_type] [py_conf] [js_src] [py_ver]
```
- width: iframeの幅を指定します。デフォルトは500です。
- height: iframeの高さを指定します。デフォルトは500です。
- background: iframeの背景色を指定します。デフォルトはwhiteです。
- py_val: PyScriptの変数を''で囲んだJSON形式で指定します。デフォルトは'{}'です。
- p5_global: p5playをグローバルモードと同様のコーディングができるようにするかどうかを指定します。デフォルトはTrueです。
- p5_type: 実行するp5.jsの種類。q5またはp5を指定します。q5は軽量p5互換ライブラリのq5.js、p5はp5.jsを使います。デフォルトはq5です。
- p5play_use: p5play.jsを使うかどうかを指定します。デフォルトはFalseです。
- py_type: 実行するPythonの種類。pyまたはmpyを指定します。mpyはMicroPyton、pyはCPython互換のPyodideで実行します。デフォルトはmpyです。グローバルモードのときはmpy固定です。
- py_conf: PyScriptの設定を''で囲んだJSON形式で指定します。デフォルトは'{}'です。
- js_src: 外部JavaScriptのURLを''で囲んだ文字列のJSON配列形式で指定します。デフォルトは'[]'です。
- py_ver: PyScriptのバージョンを指定します。
#### %%genp5
セル内のp5play.jsライブラリを使ったPythonコードからブラウザで実行可能な単一HTMLを生成するマジックコマンド。オプションはrunp5と同じです。
```juypyter
%%genp5 [width] [height] [background] [p5_global] [p5_type] [p5play_use] [py_type] [py_conf] [js_src] [version]
```
### ライセンス
p5play.jsはAGPL-v3ライセンス・商用ライセンスのデュアルライセンスとなっていますので使用の際は確認してください。
Raw data
{
"_id": null,
"home_page": null,
"name": "p5magic",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "PyScript, jupyter, magic, colab, iframe, p5.js, q5.js, processing, creative coding, p5play.js",
"author": "Uniras",
"author_email": "tkappeng@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/87/25/7a152d177860b0cf685ae7591852766a04296cc06f47af0fbd45bb9459c3/p5magic-2.5.0.tar.gz",
"platform": null,
"description": "# P5 Magic Command\r\n\r\n## \u6982\u8981\r\n\r\nJypyter(notebook/lab)\u30fbVSCode\u307e\u305f\u306fGoogle Colab\u3067p5.js/q5.js/p5play.js\u3092\u4f7f\u3063\u305f\u30b3\u30fc\u30c9\u30bb\u30eb\u306ePython\u30b3\u30fc\u30c9\u3092PyScript\u3092\u4f7f\u3063\u3066iframe(\u30d6\u30e9\u30a6\u30b6)\u4e0a\u3067\u5b9f\u884c\u3059\u308b\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u3067\u3059\u3002\r\n\r\n## \u4f7f\u3044\u65b9\r\n\r\n### \u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u306e\u8ffd\u52a0\r\n\r\n\u30b3\u30fc\u30c9\u30bb\u30eb\u306b\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u3092\u8cbc\u308a\u4ed8\u3051\u3066\u5b9f\u884c\u3057\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u3092\u767b\u9332\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30ab\u30fc\u30cd\u30eb\u3084\u30e9\u30f3\u30bf\u30a4\u30e0\u3092\u518d\u8d77\u52d5\u3059\u308b\u5ea6\u306b\u518d\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\r\n\r\n```python\r\n%pip install -q -U pysmagic p5magic\r\nfrom p5magic import register_p5magic\r\n\r\nregister_p5magic()\r\n```\r\n\r\n### \u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u306e\u4f7f\u3044\u65b9\r\n\r\n\u30b3\u30fc\u30c9\u30bb\u30eb\u306e\u5192\u982d\u306b\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u3092\u8a18\u8ff0\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u5b9f\u884c\u3059\u308b\u3068\u30a2\u30a6\u30c8\u30d7\u30c3\u30c8\u306biframe\u304c\u8868\u793a\u3055\u308c\u3066\u305d\u306e\u4e2d\u3067\u30b3\u30fc\u30c9\u30bb\u30eb\u306e\u30b3\u30fc\u30c9\u304cPyScript\u3067\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002\u30b0\u30ed\u30fc\u30d0\u30eb\u30e2\u30fc\u30c9\u53ca\u3073\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30e2\u30fc\u30c9\u306e\u4e21\u65b9\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u3059\u3002\r\n\r\n\u4ee5\u4e0b\u306f\u3001q5.js\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3063\u3066\u63cf\u753b\u3057\u305f\u8d64\u3044\u5186\u3092\u77e2\u5370\u30ad\u30fc\u3067\u52d5\u304b\u3059\u4f8b\u3067\u3059\u3002\r\n\r\n#### \u30b0\u30ed\u30fc\u30d0\u30eb\u30e2\u30fc\u30c9\r\n\r\n```python\r\n%%runp5\r\n\r\nx = 100\r\ny = 100\r\n\r\ndef setup():\r\n p5.createCanvas(300, 300)\r\n\r\ndef draw():\r\n global x, y\r\n background(128)\r\n fill(255, 0, 0)\r\n ellipse(x, y, 50, 50)\r\n\r\n if keyIsDown(LEFT_ARROW):\r\n x -= 1\r\n if keyIsDown(RIGHT_ARROW):\r\n x += 1\r\n if keyIsDown(UP_ARROW):\r\n y -= 1\r\n if keyIsDown(DOWN_ARROW):\r\n y += 1\r\n```\r\n\r\n#### \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30e2\u30fc\u30c9\r\n\r\n```python\r\n%%runp5 500 500 white '{}' False\r\n\r\nimport pyscript\r\nimport js\r\n\r\ndef sketch(p5):\r\n x = 100\r\n y = 100\r\n\r\n def setup():\r\n p5.createCanvas(300, 300)\r\n\r\n def draw():\r\n nonlocal x, y\r\n p5.background(128)\r\n p5.fill(255, 0, 0)\r\n p5.ellipse(x, y, 50, 50)\r\n\r\n if p5.keyIsDown(p5.LEFT_ARROW):\r\n x -= 1\r\n if p5.keyIsDown(p5.RIGHT_ARROW):\r\n x += 1\r\n if p5.keyIsDown(p5.UP_ARROW):\r\n y -= 1\r\n if p5.keyIsDown(p5.DOWN_ARROW):\r\n y += 1\r\n\r\n p5.setup = setup\r\n p5.draw = draw\r\n\r\njs.p5start(sketch)\r\n```\r\n\r\n### \u30b0\u30ed\u30fc\u30d0\u30eb\u5909\u6570\r\n\r\nPyScript\u304b\u3089\u4ee5\u4e0b\u306e\u5909\u6570\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002\r\n\r\n- \u5225\u306e\u30bb\u30eb\u3067\u8a2d\u5b9a\u3057\u305f\u30b0\u30ed\u30fc\u30d0\u30eb\u5909\u6570(_\u3067\u59cb\u307e\u308b\u5909\u6570\u540d\u3084JSON\u306b\u5909\u63db\u3067\u304d\u306a\u3044\u3082\u306e\u306f\u9664\u304f)\r\n- \u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u306e\u5f15\u6570py_val\u3067\u8a2d\u5b9a\u3057\u305f\u5909\u6570\r\n- width: iframe\u306e\u5e45(\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u306e\u5f15\u6570\u3067\u6307\u5b9a\u3057\u305f\u5e45)\r\n- height: iframe\u306e\u9ad8\u3055(\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u306e\u5f15\u6570\u3067\u6307\u5b9a\u3057\u305f\u9ad8\u3055)\r\n\r\n\u3053\u306e\u5909\u6570\u306fjs.pys\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u4ecb\u3057\u3066\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002\r\n\u5909\u6570\u540d\u304c\u885d\u7a81\u3057\u305f\u5834\u5408\u306f\u4e0a\u8a18\u30ea\u30b9\u30c8\u306e\u9806\u306b\u4e0a\u66f8\u304d\u3055\u308c\u3066\u9069\u7528\u3055\u308c\u307e\u3059\u3002\r\n\r\n### \u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\r\n\r\n#### %%runp5\r\n\r\n\u30bb\u30eb\u5185\u306ep5play.js\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3063\u305fPython\u30b3\u30fc\u30c9\u3092PyScript\u3092\u7528\u3044\u3066iframe\u5185\u3067\u5b9f\u884c\u3059\u308b\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\r\n\r\n```juypyter\r\n%%runp5 [width] [height] [background] [py_val] [p5_global] [p5_type] [p5play_use] [py_type] [py_conf] [js_src] [py_ver]\r\n```\r\n\r\n- width: iframe\u306e\u5e45\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306f500\u3067\u3059\u3002\r\n- height: iframe\u306e\u9ad8\u3055\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306f500\u3067\u3059\u3002\r\n- background: iframe\u306e\u80cc\u666f\u8272\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306fwhite\u3067\u3059\u3002\r\n- py_val: PyScript\u306e\u5909\u6570\u3092''\u3067\u56f2\u3093\u3060JSON\u5f62\u5f0f\u3067\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306f'{}'\u3067\u3059\u3002\r\n- p5_global: p5play\u3092\u30b0\u30ed\u30fc\u30d0\u30eb\u30e2\u30fc\u30c9\u3068\u540c\u69d8\u306e\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u304b\u3069\u3046\u304b\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306fTrue\u3067\u3059\u3002\r\n- p5_type: \u5b9f\u884c\u3059\u308bp5.js\u306e\u7a2e\u985e\u3002q5\u307e\u305f\u306fp5\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002q5\u306f\u8efd\u91cfp5\u4e92\u63db\u30e9\u30a4\u30d6\u30e9\u30ea\u306eq5.js\u3001p5\u306fp5.js\u3092\u4f7f\u3044\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306fq5\u3067\u3059\u3002\r\n- p5play_use: p5play.js\u3092\u4f7f\u3046\u304b\u3069\u3046\u304b\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306fFalse\u3067\u3059\u3002\r\n- py_type: \u5b9f\u884c\u3059\u308bPython\u306e\u7a2e\u985e\u3002py\u307e\u305f\u306fmpy\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002mpy\u306fMicroPyton\u3001py\u306fCPython\u4e92\u63db\u306ePyodide\u3067\u5b9f\u884c\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306fmpy\u3067\u3059\u3002\u30b0\u30ed\u30fc\u30d0\u30eb\u30e2\u30fc\u30c9\u306e\u3068\u304d\u306fmpy\u56fa\u5b9a\u3067\u3059\u3002\r\n- py_conf: PyScript\u306e\u8a2d\u5b9a\u3092''\u3067\u56f2\u3093\u3060JSON\u5f62\u5f0f\u3067\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306f'{}'\u3067\u3059\u3002\r\n- js_src: \u5916\u90e8JavaScript\u306eURL\u3092''\u3067\u56f2\u3093\u3060\u6587\u5b57\u5217\u306eJSON\u914d\u5217\u5f62\u5f0f\u3067\u6307\u5b9a\u3057\u307e\u3059\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u306f'[]'\u3067\u3059\u3002\r\n- py_ver: PyScript\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\r\n\r\n#### %%genp5\r\n\r\n\u30bb\u30eb\u5185\u306ep5play.js\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3063\u305fPython\u30b3\u30fc\u30c9\u304b\u3089\u30d6\u30e9\u30a6\u30b6\u3067\u5b9f\u884c\u53ef\u80fd\u306a\u5358\u4e00HTML\u3092\u751f\u6210\u3059\u308b\u30de\u30b8\u30c3\u30af\u30b3\u30de\u30f3\u30c9\u3002\u30aa\u30d7\u30b7\u30e7\u30f3\u306frunp5\u3068\u540c\u3058\u3067\u3059\u3002\r\n\r\n```juypyter\r\n%%genp5 [width] [height] [background] [p5_global] [p5_type] [p5play_use] [py_type] [py_conf] [js_src] [version]\r\n```\r\n\r\n### \u30e9\u30a4\u30bb\u30f3\u30b9\r\n\r\np5play.js\u306fAGPL-v3\u30e9\u30a4\u30bb\u30f3\u30b9\u30fb\u5546\u7528\u30e9\u30a4\u30bb\u30f3\u30b9\u306e\u30c7\u30e5\u30a2\u30eb\u30e9\u30a4\u30bb\u30f3\u30b9\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u306e\u3067\u4f7f\u7528\u306e\u969b\u306f\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002\r\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "This Python package is a magic command that executes Python code in code cells on Jupyter and Google Colab using PyScript within an iframe.",
"version": "2.5.0",
"project_urls": {
"Homepage": "https://github.com/uniras/P5Magic",
"Repository": "https://github.com/uniras/P5Magic"
},
"split_keywords": [
"pyscript",
" jupyter",
" magic",
" colab",
" iframe",
" p5.js",
" q5.js",
" processing",
" creative coding",
" p5play.js"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "7a3c3af18ad0358baf796532b8f55f0b4b37183f7e83f0d7b0f7c7a3a981f78a",
"md5": "b0ac06ca2fa138d1d1769a8108bc2178",
"sha256": "07d19fe61513991ec0829999f2d4e1dac5cd24b66772bea8aa98108575c3d69a"
},
"downloads": -1,
"filename": "p5magic-2.5.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b0ac06ca2fa138d1d1769a8108bc2178",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 5873,
"upload_time": "2024-11-23T20:21:20",
"upload_time_iso_8601": "2024-11-23T20:21:20.456685Z",
"url": "https://files.pythonhosted.org/packages/7a/3c/3af18ad0358baf796532b8f55f0b4b37183f7e83f0d7b0f7c7a3a981f78a/p5magic-2.5.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "87257a152d177860b0cf685ae7591852766a04296cc06f47af0fbd45bb9459c3",
"md5": "3009de31bb6b1c1843e503fd4926cc8e",
"sha256": "986ad42f843903be70adc5b688585bf4cdd2d631066db92efdf516df0885046b"
},
"downloads": -1,
"filename": "p5magic-2.5.0.tar.gz",
"has_sig": false,
"md5_digest": "3009de31bb6b1c1843e503fd4926cc8e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 5285,
"upload_time": "2024-11-23T20:21:22",
"upload_time_iso_8601": "2024-11-23T20:21:22.164779Z",
"url": "https://files.pythonhosted.org/packages/87/25/7a152d177860b0cf685ae7591852766a04296cc06f47af0fbd45bb9459c3/p5magic-2.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-23 20:21:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "uniras",
"github_project": "P5Magic",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "p5magic"
}