diff --git a/README.md b/README.md index 6604c40..5751fc1 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,12 @@ 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 ### Supported inline types Parkdown currently support the following block types: -* bold text (`**bold**`) +* bold text (`**bold**`) * italic text (`*italic*`) * code snippets * images (``) @@ -26,7 +27,6 @@ Parkdown currently support the following block types: * 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)* @@ -43,6 +43,21 @@ or via reference to [a later defined url][massivedynamic], i we so desire.  + +### Block quotes +```markdown +> Only two things are infinite, +> the universe and hima stupidity, +> i am not totally shure about the universe, though... +> - Albert Einstein +``` + + +> Only two things are infinite, +> the universe and hima stupidity, +> i am not totally shure about the universe, though... +> - Albert Einstein + ### Code blocks ```markdown diff --git a/src/Lexer.php b/src/Lexer.php index 82b9222..f2c6c0e 100644 --- a/src/Lexer.php +++ b/src/Lexer.php @@ -87,6 +87,10 @@ class Lexer { $clearBuffer(); array_push($tokens, new Token(TokenType::BACKSLASH, $char)); break; + case '>': + $clearBuffer(); + array_push($tokens, new Token(TokenType::GT, $char)); + break; case ':': if (str_ends_with($buffer, "http") || str_ends_with($buffer, "https")) { $buffer .= $char; diff --git a/src/Parser.php b/src/Parser.php index 27a7a5d..f40eb52 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -48,6 +48,31 @@ class Parser { return stripslashes($text); } + private function resolveReferences(DOMElement $node) : void { + if (count($this->references) < 1) + return; + + if ($node->hasAttribute("href")) { + $href = $node->getAttribute("href"); + if (substr($href, 0, 1) === self::MAGIC_CHAR) { + $index = substr($href, 1, strlen($href) - 2); + if (array_key_exists($index, $this->references)) + $node->setAttribute("href", $this->references[$index]); + } + } + if ($node->hasChildNodes()) { + foreach ($node->childNodes as $child) { + if ($child->nodeType === XML_ELEMENT_NODE) + $this->resolveReferences($child); + } + } + } + + public function debug() : void { + echo "
"; + print_r($this->tokenStream); + echo ""; + } // PARSING private function parseBold() : DOMNode { @@ -405,30 +430,28 @@ class Parser { $this->document->appendChild($elm); } - private function resolveReferences(DOMElement $node) : void { - if (count($this->references) < 1) + private function parseBlockQuote() : void { + if (!str_starts_with($this->next()->data, " ")) { + $this->buildParagraph($this->parseText()); return; - - if ($node->hasAttribute("href")) { - $href = $node->getAttribute("href"); - if (substr($href, 0, 1) === self::MAGIC_CHAR) { - $index = substr($href, 1, strlen($href) - 2); - if (array_key_exists($index, $this->references)) - $node->setAttribute("href", $this->references[$index]); - } } - if ($node->hasChildNodes()) { - foreach ($node->childNodes as $child) { - if ($child->nodeType === XML_ELEMENT_NODE) - $this->resolveReferences($child); + $buffer = ""; + $elm = $this->document->createElement("blockquote", $buffer); + while (!($this->current()->type === TokenType::EOL && $this->next()->type !== TokenType::GT)) { + $gt = $this->consume(); + if ($this->current()->type === TokenType::EOL) { + $this->consume(); + $line = $this->document->createTextNode($buffer); + $br = $this->document->createElement("br"); + $buffer = ""; + $elm->appendChild($line); + $elm->appendChild($br); + continue; } + $buffer .= $this->current()->data; } - } - public function debug() : void { - echo "
"; - print_r($this->tokenStream); - echo ""; + $this->document->appendChild($elm); } public function parse() : DOMDocument { @@ -455,6 +478,9 @@ class Parser { case TokenType::PIPE: $this->parseTable(); break; + case TokenType::GT: + $this->parseBlockQuote(); + break; case TokenType::TEXT: default: $this->buildParagraph($this->parseText(true)); diff --git a/src/Token.php b/src/Token.php index 967e875..ce9a814 100644 --- a/src/Token.php +++ b/src/Token.php @@ -20,6 +20,7 @@ enum TokenType { case COLON ; case BACKSLASH; case PIPE ; + case GT ; } class Token {