parent
5acd3b362e
commit
aaa15ce893
2 changed files with 239 additions and 0 deletions
@ -0,0 +1,35 @@ |
||||
<?php declare(strict_types=1); |
||||
|
||||
require __DIR__."/../vendor/autoload.php"; |
||||
|
||||
$source = file_get_contents("php://input"); |
||||
|
||||
try { |
||||
$Instance = new parkdown\Parkdown($source, true); |
||||
echo $Instance->html(); |
||||
} catch (parkdown\ParserError $error) { |
||||
echo "<pre>"; |
||||
|
||||
$message = explode(" ", $error->getMessage()); |
||||
$location = array_shift($message); |
||||
$loc = explode(":", $location); |
||||
$file = array_shift($loc); |
||||
$line = substr(implode(":", $loc), 0, -1); |
||||
[$row, $col] = explode(":", $line); |
||||
|
||||
echo "<a class='error' href=\"javascript: highlight($col, $row);\">$location</a> ".implode(" ", $message); |
||||
|
||||
|
||||
$stackTrace = explode("\n", $error->getTraceAsString()); |
||||
|
||||
echo "<p><small>"; |
||||
foreach ($stackTrace as $step) { |
||||
$step = explode(" ", $step); |
||||
array_shift($step); |
||||
$location = array_shift($step); |
||||
$location = preg_replace("/\(([0-9]+)\):/", ":\$1:", $location); |
||||
|
||||
echo "<a class='error' href='vscode://file/".substr($location, 0, -1)."'>$location</a> ".implode(" ", $step)."<br>"; |
||||
} |
||||
echo "</small></p>"; |
||||
} |
@ -0,0 +1,204 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<title>parkdown playground</title> |
||||
<script type="module"> |
||||
const $ = selector => { |
||||
const elements = document.querySelectorAll(selector); |
||||
|
||||
return elements.length < 2 ? elements[0] : elements; |
||||
}; |
||||
|
||||
const output = $("#output"); |
||||
const input = $("#input"); |
||||
const numbers = $(".linenumbers"); |
||||
let timeout; |
||||
|
||||
const updateOutput = (event) => { |
||||
const text = event ? event.target.value : input.value; |
||||
const lines = text.split("\n").length; |
||||
let html = ""; |
||||
for (let i = 1; i <= lines; i++) { |
||||
html += `${i}<br>`; |
||||
} |
||||
numbers.innerHTML = html; |
||||
|
||||
timeout = setTimeout(() => { |
||||
|
||||
fetch("ajax.php", { |
||||
method : "POST", |
||||
headers: { |
||||
"Content-Type" : "application/json" |
||||
}, |
||||
body : text |
||||
}).then(response => response.text()).then(text => output.innerHTML = text); |
||||
}, 1000); |
||||
} |
||||
|
||||
document.addEventListener("DOMContentLoaded", () => { |
||||
updateOutput(); |
||||
|
||||
input.addEventListener("keydown", event => { |
||||
if (event.key !== "Tab") |
||||
return; |
||||
event.preventDefault(); |
||||
const start = input.selectionStart; |
||||
const end = input.selectionEnd; |
||||
const value = input.value; |
||||
|
||||
input.value = value.substring(0, start) + "\t" + value.substring(end); |
||||
input.selectionStart = input.selectionEnd = (start + 1); |
||||
}); |
||||
|
||||
input.addEventListener("input", event => { |
||||
clearTimeout(timeout); |
||||
updateOutput(event); |
||||
}); |
||||
}); |
||||
|
||||
window.highlight = (col, row) => { |
||||
const lines = input.value.split("\n"); |
||||
|
||||
let start = 0; |
||||
let end = 0; |
||||
let i = 0; |
||||
|
||||
for (const line of lines) { |
||||
if (++i === row) { |
||||
end = start + line.length; |
||||
break; |
||||
} |
||||
start += line.length + 1; |
||||
} |
||||
|
||||
start = start + col - 1 === end ? start : start + col; |
||||
|
||||
input.focus(); |
||||
input.setSelectionRange(start, end); |
||||
const lineHeight = input.clientHeight / lines.length; |
||||
$(".editor").scrollTop = lineHeight * (row - 10); |
||||
input.scrollLeft = 0; |
||||
}; |
||||
</script> |
||||
<style rel="stylesheet"> |
||||
* { |
||||
box-sizing: border-box; |
||||
outline: 0 !important; |
||||
} |
||||
|
||||
a { |
||||
color: dodgerblue; |
||||
text-decoration: none; |
||||
} |
||||
a:hover { |
||||
text-decoration: underline; |
||||
} |
||||
a.error { |
||||
color: palevioletred; |
||||
} |
||||
|
||||
body { |
||||
display: grid; |
||||
grid-template-columns: 1fr 1fr; |
||||
font-family: sans-serif; |
||||
margin: 0; |
||||
padding: 0; |
||||
height: 100vh; |
||||
overflow: hidden; |
||||
background: #333; |
||||
color: #eee; |
||||
} |
||||
|
||||
body > * { |
||||
width: 100%; |
||||
border: solid 1px #111; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
textarea { |
||||
width: 100%; |
||||
height: 100%; |
||||
font-family: monospace; |
||||
box-sizing: content-box; |
||||
background: transparent; |
||||
tab-size: 4; |
||||
border: none; |
||||
padding-bottom: 4rem; |
||||
font-size: 1.2rem; |
||||
overflow-y: clip; |
||||
overflow-x: scroll; |
||||
white-space: nowrap; |
||||
resize: none; |
||||
margin: 1rem 0; |
||||
color: #FAF08B; |
||||
} |
||||
textarea::selection { |
||||
background-color: dodgerblue; |
||||
color: white; |
||||
} |
||||
|
||||
.editor { |
||||
display: grid; |
||||
grid-template-columns: 80px auto; |
||||
gap: 2rem; |
||||
height: 100%; |
||||
border-right: none; |
||||
overflow-y: auto; |
||||
overflow-x: hidden; |
||||
} |
||||
|
||||
.linenumbers { |
||||
font-size: 1.2rem; |
||||
text-align: right; |
||||
padding: 1rem; |
||||
color: #aaa; |
||||
font-family: monospace; |
||||
background: #222; |
||||
} |
||||
|
||||
#output { |
||||
overflow-y: auto; |
||||
padding: 4rem; |
||||
} |
||||
|
||||
::-webkit-scrollbar { |
||||
background-color: transparent; |
||||
width: 16px; |
||||
} |
||||
::-webkit-scrollbar-track { |
||||
background-color: transparent; |
||||
} |
||||
::-webkit-scrollbar-thumb { |
||||
background-color: rgba(255,255,255,0.1); |
||||
border-radius: 16px; |
||||
border: 4px solid #333; |
||||
} |
||||
::-webkit-scrollbar-button { |
||||
display:none; |
||||
} |
||||
</style> |
||||
</head> |
||||
<body> |
||||
|
||||
<section class="editor"> |
||||
<section class="linenumbers">1</section> |
||||
<textarea id="input"> |
||||
# parkdown playground |
||||
|
||||
 |
||||
|
||||
* use markdown in the editor |
||||
* view result over there |
||||
|
||||
View parkdown code [here][code]. |
||||
|
||||
[code]: https://git.mike-ochmann.de/MassiveDynamic/Parkdown |
||||
</textarea> |
||||
</section> |
||||
<section id="output"></section> |
||||
|
||||
</body> |
||||
</html> |
Loading…
Reference in new issue