| <html> |
| <head> |
| <title> |
| Python on the Web |
| </title> |
| <link id="bespin_base" href="skywriter/"/> |
| <script src="skywriter/BespinEmbedded.js"></script> |
| <style type="text/css"> |
| .bespin { |
| width: 80%; |
| height: 30%; |
| } |
| </style> |
| |
| <!-- |
| The attached python.js (or python.cc.js) is CPython 2.7.1, licensed under |
| the PSF: http://docs.python.org/license.html |
| |
| Additional steps to create this demo: |
| |
| * Compile with _PyRun_SimpleStringFlags exported in EXPORTED_FUNCTIONS |
| * Find the actual name of that function (closure changes it, see .vars), and use it as per the XXX comment below. |
| --> |
| |
| <script> |
| var Module = { |
| noInitialRun: true |
| }; |
| </script> |
| <script src="python.cc.js"></script> |
| <script> |
| var orig = Module._PyRun_SimpleStringFlags; |
| var RAN_ALREADY; |
| QDb = function() { // XXX Have the actual name here! See comment above. |
| if(!RAN_ALREADY) { |
| RAN_ALREADY = true; |
| throw "halting, since this is the first run"; |
| } |
| orig.apply(null, arguments); |
| } |
| |
| // print function which the Python engine will call |
| var lines = [], printed = false; |
| |
| function print(text, force) { |
| //force = true; // XXX - for debugging |
| lines.push(text); |
| printed = true; |
| |
| if (force) { |
| var element = document.getElementById('output'); |
| element.value = text; |
| } |
| } |
| |
| function execute(text) { |
| lines = []; |
| printed = false; |
| |
| var element = document.getElementById('output'); |
| if (!element) return; // perhaps during startup |
| |
| var ptr = Module.Pointer_make(Module.intArrayFromString(text), 0, 2, 'i8'); // leak! |
| try { |
| Module._PyRun_SimpleStringFlags(ptr, 0); |
| } catch(e) { |
| if (e === 'halting, since this is the first run') { |
| return; |
| } |
| element.value = 'JS crash:\n\n' + e + '\n\nPlease let us know about this problem!\n' + element.value; |
| return; |
| } |
| |
| if (printed) { |
| element.value = element.value + lines.join('\n') + '\n'; |
| // scroll down |
| var len = element.textLength; |
| element.setSelectionRange(len-1, len); |
| } |
| } |
| |
| var editor; |
| |
| function doRun() { |
| args = ['-S', '-c', 'print 5']; |
| try { |
| Module.run(args); |
| } catch (e) { |
| if (e !== 'halting, since this is the first run') { |
| throw e; |
| } |
| } |
| setTimeout(function() { |
| if (!bespin.useBespin) setTimeout(arguments.callee, 10); |
| bespin.useBespin(document.getElementById('the_input'), { "stealFocus":true, "syntax": "python" }).then(function(env) { |
| editor = env.editor; |
| }); |
| }, 10); |
| } |
| |
| </script> |
| </head> |
| <body onload="doRun(); document.getElementById('the_input').focus()"> |
| <h1>Python on the Web</h1> |
| <p> |
| This is CPython, the standard <a href="http://www.python.org">Python</a> implementation, compiled from C to |
| JavaScript using <a href="http://emscripten.org">Emscripten</a>, |
| running in your browser (without any plugins). It is both a tech demo and also a usable tool, for example, to |
| assist in teaching people Python by just visiting a website (instead of installing Python locally). |
| </p> |
| <p> |
| Notes: |
| <ul> |
| <li>Most core language stuff should work, except for importing non-static modules (in other words, <code>import sys</code> will |
| work, but other modules won't).</li> |
| <li>Please report bugs if you find them!</li> |
| <li>The editor is <a href="https://mozillalabs.com/skywriter/">Skywriter</a>. |
| </ul> |
| </p> |
| <hr> |
| <!-- Call Python's execution function --> |
| <form onsubmit="execute(editor.value); return false"> |
| <b>Enter some Python</b>: |
| <input type="submit" value="execute"> |
| <div id="the_input">import sys |
| print 'Hello %s, here are some numbers:' % raw_input('What is your name?'), [2*x for x in range(5)][:4] |
| print 'This is Python {} on {}'.format(sys.version, sys.platform) |
| </div> |
| </form> |
| <hr> |
| <textarea id="output" style="font-family: monospace; width: 80%" rows="8" readonly></textarea> |
| </body> |
| </html> |