|
|
<!DOCTYPE html> |
|
|
<html lang="en" class="dark"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Python Code Runner</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> |
|
|
<script src="https://unpkg.com/feather-icons"></script> |
|
|
<script src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"></script> |
|
|
<style> |
|
|
.cm-editor { |
|
|
height: 100% !important; |
|
|
font-size: 14px !important; |
|
|
} |
|
|
.cm-scroller { |
|
|
font-family: 'Fira Code', monospace !important; |
|
|
} |
|
|
.cm-gutters { |
|
|
background-color: #111827 !important; |
|
|
border-right: 1px solid #374151 !important; |
|
|
} |
|
|
.cm-activeLineGutter { |
|
|
background-color: #1f2937 !important; |
|
|
} |
|
|
.cm-content { |
|
|
caret-color: white !important; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-900 text-gray-100 min-h-screen flex flex-col"> |
|
|
<header class="bg-black border-b border-gray-800 py-4 px-6"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<i data-feather="code" class="text-green-500"></i> |
|
|
<h1 class="text-xl font-bold">DarkPythonPlayground</h1> |
|
|
</div> |
|
|
<div class="flex items-center space-x-4"> |
|
|
<button id="run-btn" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-md flex items-center space-x-2 transition duration-200"> |
|
|
<i data-feather="play" class="w-4 h-4"></i> |
|
|
<span>Run</span> |
|
|
</button> |
|
|
<button id="theme-toggle" class="p-2 rounded-md hover:bg-gray-800 transition duration-200"> |
|
|
<i data-feather="moon" class="w-5 h-5"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
<main class="flex-1 flex flex-col md:flex-row overflow-hidden"> |
|
|
<div class="flex-1 border-r border-gray-800 overflow-hidden"> |
|
|
<div id="editor" class="h-full w-full"></div> |
|
|
</div> |
|
|
<div class="flex-1 flex flex-col overflow-hidden"> |
|
|
<div class="border-b border-gray-800 py-2 px-4 flex items-center"> |
|
|
<i data-feather="terminal" class="text-green-500 mr-2"></i> |
|
|
<h2 class="font-medium">Output</h2> |
|
|
</div> |
|
|
<div id="output" class="flex-1 overflow-auto p-4 font-mono text-sm bg-gray-800"></div> |
|
|
</div> |
|
|
</main> |
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/codemirror.min.js"></script> |
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/mode/python/python.min.js"></script> |
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/addon/edit/matchbrackets.min.js"></script> |
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/addon/edit/closebrackets.min.js"></script> |
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/theme/dracula.min.js"></script> |
|
|
<script> |
|
|
feather.replace(); |
|
|
|
|
|
let pyodide; |
|
|
async function initializePyodide() { |
|
|
pyodide = await loadPyodide({ |
|
|
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.23.4/full/" |
|
|
}); |
|
|
await pyodide.loadPackage("micropip"); |
|
|
} |
|
|
|
|
|
const editor = CodeMirror(document.getElementById('editor'), { |
|
|
mode: 'python', |
|
|
lineNumbers: true, |
|
|
theme: 'dracula', |
|
|
autoCloseBrackets: true, |
|
|
matchBrackets: true, |
|
|
indentUnit: 4, |
|
|
tabSize: 4, |
|
|
value: `# Welcome to DarkPythonPlayground!\n# Write your Python code here and click Run\n\ndef greet(name):\n return f"Hello, {name}!"\n\nprint(greet("Python Developer"))` |
|
|
}); |
|
|
|
|
|
document.getElementById('run-btn').addEventListener('click', async () => { |
|
|
if (!pyodide) { |
|
|
await initializePyodide(); |
|
|
} |
|
|
|
|
|
const code = editor.getValue(); |
|
|
const outputDiv = document.getElementById('output'); |
|
|
outputDiv.innerHTML = '<span class="text-gray-400">Running...</span>'; |
|
|
|
|
|
try { |
|
|
const result = await pyodide.runPythonAsync(code); |
|
|
if (result !== undefined) { |
|
|
outputDiv.innerHTML = `<span class="text-green-400">${result}</span>`; |
|
|
} else { |
|
|
outputDiv.innerHTML = '<span class="text-green-400">Code executed successfully!</span>'; |
|
|
} |
|
|
} catch (error) { |
|
|
outputDiv.innerHTML = `<span class="text-red-400">${error}</span>`; |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const themeToggle = document.getElementById('theme-toggle'); |
|
|
themeToggle.addEventListener('click', () => { |
|
|
const html = document.documentElement; |
|
|
if (html.classList.contains('dark')) { |
|
|
html.classList.remove('dark'); |
|
|
themeToggle.innerHTML = '<i data-feather="sun" class="w-5 h-5"></i>'; |
|
|
feather.replace(); |
|
|
} else { |
|
|
html.classList.add('dark'); |
|
|
themeToggle.innerHTML = '<i data-feather="moon" class="w-5 h-5"></i>'; |
|
|
feather.replace(); |
|
|
} |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|