added new default text

feature/strict-mode
Michael Ochmann 3 years ago
parent fb5df71101
commit 1d55913f85
  1. 171
      playground/index.php
  2. 28
      src/Parser.php

@ -186,16 +186,175 @@
<section class="editor"> <section class="editor">
<section class="linenumbers">1</section> <section class="linenumbers">1</section>
<textarea id="input"> <textarea id="input">
# parkdown playground # Parkdown
– a simple recursive descent Markdown parser for PHP *(version >= 8.1)*
![parkdown logo](https://git.mike-ochmann.de/MassiveDynamic/Parkdown/raw/branch/master/docs/logo_parkdown.svg) ![Markdown is a simple markup language](https://git.mike-ochmann.de/MassiveDynamic/Parkdown/raw/branch/master/docs/logo_parkdown.svg)
* use markdown in the editor ## Specification
* view result over there
View parkdown code [here][code]. ### 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)
[code]: https://git.mike-ochmann.de/MassiveDynamic/Parkdown ### 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 (`![alt text](src url)`)
* 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
![this is an alt text](https://images.unsplash.com/photo-1571171637578-41bc2dd41cd2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=300&w=1740&q=80\)
```
![this is an alt text](https://images.unsplash.com/photo-1571171637578-41bc2dd41cd2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=300&w=1740&q=80)
### 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> </textarea>
</section> </section>
<section id="output"></section> <section id="output"></section>

@ -83,6 +83,14 @@ class Parser {
assert($assertion, new ParserError(self::LOC($token->location).$message)); assert($assertion, new ParserError(self::LOC($token->location).$message));
} }
public static function TextToSlug(string $html) : string {
$out = trim(strip_tags($html));
$out = strtolower($out);
$out = str_replace(" ", "_", $out);
return $out;
}
private function resolveReferences(DOMElement $node) : void { private function resolveReferences(DOMElement $node) : void {
if (count($this->references) < 1) if (count($this->references) < 1)
return; return;
@ -173,7 +181,7 @@ class Parser {
$backtick = $this->consume(); $backtick = $this->consume();
self::Assert($backtick->type === TokenType::BACKTICK, $backtick, "inline code expression not autmatically closed (expected backtick)"); self::Assert($backtick->type === TokenType::BACKTICK, $backtick, "inline code expression not autmatically closed (expected backtick)");
return $this->document->createElement("code", $buffer); return @$this->document->createElement("code", $buffer);
} }
private function parseLink() : ?DOMNode { private function parseLink() : ?DOMNode {
@ -246,7 +254,11 @@ class Parser {
continue; continue;
} elseif ($this->current()->type === TokenType::BACKTICK) { } elseif ($this->current()->type === TokenType::BACKTICK) {
$clearBuffer(); $clearBuffer();
array_push($elms, $this->parseCode()); $code = $this->parseCode();
self::Assert($code !== false, $this->current(), "malformed code block");
array_push($elms, $code);
continue; continue;
} elseif ($this->current()->type === TokenType::LBRACKET) { } elseif ($this->current()->type === TokenType::LBRACKET) {
$links = $this->parseLink(); $links = $this->parseLink();
@ -364,14 +376,17 @@ class Parser {
break; break;
// then we expect an asterisk or a number followed by a period // then we expect an asterisk or a number followed by a period
if ($type === ListType::UNORDERED) { if ($type === ListType::UNORDERED) {
$asterisk = $this->consume(); if ($this->current()->type === TokenType::ASTERISK)
self::Assert($asterisk->type === TokenType::ASTERISK, $asterisk, "expected asterisk, got ".$asterisk->type->name); $this->consume();
} else { } else {
$number = $this->consume(); if ($this->current()->type === TokenType::NUMBER) {
self::Assert($number->type === TokenType::NUMBER, $number, "expected number, got ".$number->type->name); $this->consume();
if ($this->strict && $this->current()->type !== TokenType::DOT)
$this->insert(new Token(TokenType::DOT, ".", $this->current()->location));
$period = $this->consume(); $period = $this->consume();
self::Assert($period->type === TokenType::DOT, $period, "expected period, got ".$period->type->name); self::Assert($period->type === TokenType::DOT, $period, "expected period, got ".$period->type->name);
} }
}
// then we parse the node content // then we parse the node content
$elm = $this->document->createElement("li"); $elm = $this->document->createElement("li");
@ -444,6 +459,7 @@ class Parser {
foreach ($this->parseText() as $node) foreach ($this->parseText() as $node)
if ($node instanceof DOMNode) if ($node instanceof DOMNode)
$elm->appendChild($node); $elm->appendChild($node);
$elm->setAttribute("id", self::TextToSlug($elm->textContent));
$this->document->appendChild($elm); $this->document->appendChild($elm);
} }

Loading…
Cancel
Save