Python
JavaScript
bookmarklet
Brython
ブックマークレット

Pythonでブックマークレットを作る

More than 1 year has passed since last update.

初投稿です
Brythonを使ってPythonで書いたコードが動くブックマークレットを作りました
後半はただのコードゴルフ

Brythonってなに

http://qiita.com/ryo_grid/items/5e34220ed48f4580126d
こちらが大変参考になりました。

需要はあるの

(たぶん)ないです

とりあえず書いた

bookmarklet
javascript:
(function() {
  var py = document.createElement('script');
  py.type = 'text/python';
  py.src = 'https://example/script.py';
  document.body.appendChild(py);
  var br = document.createElement('script');
  br.src = 'https://example/brython.js';
  br.onload = function() {
    brython();
  };
  document.body.appendChild(br);
})();
/script.py
from browser import alert

alert("Hello World!")

仕組みとしては単純で</body>の直前に

<script type="text/python" src="https://example/script.py"></script>
<script src="https://example/brython.js"></script>

を追加しているだけです
brython.jsを読み込み後、onload属性を用いてbrython()を呼び出すことでページ内のtext/pythonのスクリプトが走ります。

クロスドメイン問題

Brythonは外部のスクリプトがある場合、Ajaxを使ってロードします
そのためスクリプトが置いてあるサーバーのページ以外ではブックマークレットが動かないという致命的な問題が起こります
のでHTTPヘッダーにAccess-Control-Allow-Origin: *を追加することで解決しました

短くする

ブックマークレットなので短いほうがいいはず(?)

宣言を省略し変数名を1文字に

ついでにdocumentも変数に入れとく

javascript:
(function(d,p,b) {
  p = d.createElement('script');
  p.type = 'text/python';
  p.src = 'https://example/script.py';
  d.body.appendChild(p);
  b = d.createElement('script');
  b.src = 'https://example/brython.js';
  b.onload = function() {
    brython();
  };
  d.body.appendChild(b);
})(document);

再帰化

関数名がないのでarguments.calleeで呼び出す
(関数名をつけるとスペースが入りブックマークレットとしては不適切)
if文を使わず3項演算子を使用

javascript:
(function d(d,u,c,e) {
  e = d.createElement('script');
  e.src = u + (c ? 'brython.js' : 'script.py');
  c ? (arguments.callee(d,u), e.onload = function() {
    brython();
  }) : (e.type = 'text/python');
  d.body.appendChild(e);
})(document,'https://example/',1);

スペース,改行を取り除く

javascript:(function d(d,u,c,e) {e=d.createElement('script');e.src=u+(c?'brython.js':'script.py');c?(arguments.callee(d,u),e.onload=function(){brython();}):(e.type='text/python');d.body.appendChild(e);})(document,'https://example/',1);

330文字 => 235文字
まだ長い気がするけど僕の技術では限界みたいです

終わりです、良いPythonライフを!