Files
PyCanvas/skulpt+xterm.html
2025-11-29 20:11:05 +00:00

82 lines
2.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Python in Xterm.js</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.css" />
<script src="https://cdn.jsdelivr.net/npm/xterm/lib/xterm.js"></script>
<script src="http://skulpt.org/js/skulpt.min.js"></script>
<script src="http://skulpt.org/js/skulpt-stdlib.js"></script>
<style>
#terminal {
width: 100%;
height: 100vh;
}
</style>
</head>
<body>
<div id="terminal"></div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const term = new Terminal({ cursorBlink: true });
term.open(document.getElementById('terminal'));
let inputResolve;
let inputBuffer = '';
let acceptingInput = false;
function outf(text) {
term.write(text.replace(/\n/g, '\r\n'));
}
function inputf(promptText = '') {
return new Promise(resolve => {
inputBuffer = '';
inputResolve = resolve;
acceptingInput = true;
term.write(promptText);
});
}
term.onKey(e => {
if (!acceptingInput) return;
const key = e.key;
const ev = e.domEvent;
if (ev.key === 'Enter') {
term.write('\r\n');
if (inputResolve) {
inputResolve(inputBuffer);
inputResolve = null;
acceptingInput = false;
}
} else if (ev.key === 'Backspace') {
if (inputBuffer.length > 0) {
inputBuffer = inputBuffer.slice(0, -1);
term.write('\b \b');
}
} else if (key.length === 1) {
inputBuffer += key;
term.write(key);
}
});
function runCode(code) {
term.clear();
Sk.configure({
output: outf,
read: x => Sk.builtinFiles.files[x],
inputfun: inputf,
inputfunTakesPrompt: true
});
Sk.misceval.asyncToPromise(() => Sk.importMainWithBody('<stdin>', false, code, true))
.catch(err => outf(err.toString() + '\n'));
}
// Example code to run immediately
runCode('name = input("Name: ")\nprint("Hello, " + name)');
});
</script>
</body>
</html>