aboutsummaryrefslogtreecommitdiff
path: root/demos/python.html
blob: f175f081cc9383b8f57571a874fcc7aa6c619fae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<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>