You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
8.4 KiB
393 lines
8.4 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
|
<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: pre;
|
|
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;
|
|
max-width: 100%;
|
|
}
|
|
#output code {
|
|
word-break: break-word;
|
|
white-space: break-spaces;
|
|
}
|
|
|
|
#output img {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
::-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;
|
|
}
|
|
|
|
@media (max-width: 920px) {
|
|
body {
|
|
grid-template-columns: 1fr !important;
|
|
grid-template-rows: 1fr 1fr;
|
|
}
|
|
|
|
textarea, .linenumbers {
|
|
font-size: 1rem;
|
|
}
|
|
.linenumbers {
|
|
padding: 0.5rem;
|
|
}
|
|
|
|
.editor {
|
|
grid-template-columns: 50px auto;
|
|
gap: 1rem;
|
|
}
|
|
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<section class="editor">
|
|
<section class="linenumbers">1</section>
|
|
<textarea id="input">
|
|
# Parkdown
|
|
– a simple recursive descent Markdown parser for PHP *(version >= 8.1)*
|
|
|
|

|
|
|
|
## Specification
|
|
|
|
### Index
|
|
* [Block types](#supported_block_types)
|
|
* [Inline types](#supported_inline_types)
|
|
* [Examples](#examples)
|
|
* [Paragraphs](#paragraphs)
|
|
* [Images](#images)
|
|
* [Horizontal Rules](#horizontal_rules)
|
|
* [Block quotes](#block_quotes)
|
|
* [Code blocks](#code_blocks)
|
|
* [Tables](#tables)
|
|
* [References](#references)
|
|
* [Usage](#usage)
|
|
* [Testing](#testing)
|
|
|
|
### Supported block types
|
|
Parkdown currently support the following block types:
|
|
|
|
* codeblocks *(with the ability to specify a language for the code block)*
|
|
* tables *(with alignment specification)*
|
|
* paragraphs
|
|
* block quotes
|
|
* lists *(like this one)*
|
|
* also nested
|
|
* horizontal rules `---`
|
|
|
|
### Supported inline types
|
|
Parkdown currently support the following block types:
|
|
|
|
* bold text (`**bold**`)
|
|
* italic text (`*italic*`)
|
|
* code snippets
|
|
* images (``)
|
|
* links (`[link text][url or reference]`)
|
|
|
|
### Additional functionality
|
|
|
|
* references (`[marker]: URL`)
|
|
|
|
## Examples
|
|
### Paragraphs
|
|
```markdown
|
|
A simple paragraph can contain **bold text**, `inline codeblocks` and *italic text*. We can also link [with a direct url][https://google.com] *(i.e. to google)*
|
|
or via reference to [a later defined url][massivedynamic], if we so desire.
|
|
```
|
|
|
|
A simple paragraph can contain **bold text**, `inline codeblocks` and *italic text*. We can also link [with a direct url](https://google.com) *(i.e. to google)*
|
|
or via reference to [a later defined url][massivedynamic], if we so desire.
|
|
|
|
Paragraphs can be annotated with `id` and `class` attributes:
|
|
|
|
```markdown
|
|
Paragraphs can be annotated with ids and classes {.thisIsAClass, .anotherClass, #thisIsAnID}
|
|
```
|
|
|
|
results in
|
|
|
|
Paragraphs can be annotated with ids and classes {.thisIsAClass, .anotherClass, #thisIsAnID}
|
|
|
|
```html
|
|
<p class="thisIsAClass anotherClass" id="thisIsAnID">
|
|
Paragraphs can be annotated with ids and classes
|
|
</p>
|
|
```
|
|
|
|
### Images
|
|
```markdown
|
|

|
|
```
|
|
|
|

|
|
|
|
### Horizontal rules
|
|
```markdown
|
|
---
|
|
```
|
|
|
|
---
|
|
### Block quotes
|
|
```markdown
|
|
> Only two things are infinite,
|
|
> the universe and human stupidity,
|
|
> i am not totally shure about the universe, though...
|
|
> – Albert Einstein
|
|
```
|
|
|
|
|
|
> Only two things are infinite,
|
|
> the universe and human stupidity,
|
|
> i am not totally shure about the universe, though...
|
|
> – Albert Einstein
|
|
|
|
### Code blocks
|
|
```markdown
|
|
|
|
\`\`\`php
|
|
function main(int $argc, array $argv) : int {
|
|
echo "Hello World!";
|
|
|
|
return 0;
|
|
}
|
|
\`\`\`
|
|
|
|
```
|
|
|
|
```php
|
|
function main(int $argc, array $argv) : int {
|
|
echo "Hello World!";
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
### Tables
|
|
```markdown
|
|
| Product name | Amount | Price |
|
|
|--------------|:--------:|-------:|
|
|
| Football | 7 | $18,00 |
|
|
| Golfball | 122 | $7,00 |
|
|
| Fooseball | 355 | $1,00 |
|
|
| Puck | 58 | $12,00 |
|
|
```
|
|
|
|
| Product name | Amount | Price |
|
|
|--------------|:--------:|-------:|
|
|
| Football | 7 | $18,00 |
|
|
| Golfball | 122 | $7,00 |
|
|
| Fooseball | 355 | $1,00 |
|
|
| Puck | 58 | $12,00 |
|
|
|
|
### References
|
|
|
|
```markdown
|
|
[massivedynamic]: https://massivedynamic.eu
|
|
```
|
|
|
|
[massivedynamic]: https://massivedynamic.eu
|
|
|
|
## Usage
|
|
Simply construct an new `parkdown\Parkdown` object and pass the Markdown source code to it's constructor. The parsed `DOMDocument` or it's `HTML` output can then be retrieved through the `::html()` and `::tree()` member functions.
|
|
|
|
**Example**
|
|
|
|
```php
|
|
use parkdown\Parkdown;
|
|
|
|
$source = "
|
|
This is a **bold** word in a paragraph.
|
|
";
|
|
|
|
$parser = new Parkdown($source);
|
|
$tree = $parser->tree();
|
|
|
|
print_r($tree);
|
|
echo $parser->html();
|
|
```
|
|
|
|
## Testing
|
|
Unit tests can be run via `composer`:
|
|
|
|
```
|
|
composer test
|
|
```
|
|
</textarea>
|
|
</section>
|
|
<section id="output"></section>
|
|
|
|
</body>
|
|
</html> |