implemented escaping

feature/tests
Michael Ochmann 3 years ago
parent 4c0ff45e02
commit b7eeae8626
  1. 4
      src/Lexer.php
  2. 31
      src/Parser.php
  3. 33
      src/Token.php

@ -83,6 +83,10 @@ class Lexer {
$clearBuffer(); $clearBuffer();
array_push($tokens, new Token(TokenType::PIPE, $char)); array_push($tokens, new Token(TokenType::PIPE, $char));
break; break;
case '\\':
$clearBuffer();
array_push($tokens, new Token(TokenType::BACKSLASH, $char));
break;
case ':': case ':':
if (str_ends_with($buffer, "http") || str_ends_with($buffer, "https")) { if (str_ends_with($buffer, "http") || str_ends_with($buffer, "https")) {
$buffer .= $char; $buffer .= $char;

@ -44,6 +44,10 @@ class Parser {
return $char; return $char;
} }
private static function StripBackslashes(string $text) : string {
return stripslashes($text);
}
// PARSING // PARSING
private function parseBold() : DOMNode { private function parseBold() : DOMNode {
@ -122,7 +126,16 @@ class Parser {
if ((!$paragraph && $this->current()->type === TokenType::EOL) || if ((!$paragraph && $this->current()->type === TokenType::EOL) ||
($paragraph && ($this->current()->type === TokenType::EOL && $this->next()->type === TokenType::EOL)) || $this->current()->type === TokenType::EOF) ($paragraph && ($this->current()->type === TokenType::EOL && $this->next()->type === TokenType::EOL)) || $this->current()->type === TokenType::EOF)
break; break;
if ($this->current()->type === TokenType::ASTERISK) { if ($this->current()->type === TokenType::BACKSLASH && in_array($this->next()->type, [
TokenType::BACKTICK,
TokenType::ASTERISK,
TokenType::LBRACKET,
TokenType::BANG
])) {
$this->consume()->data; // backslash
$buffer .= $this->consume()->data;
continue;
} elseif ($this->current()->type === TokenType::ASTERISK) {
$clearBuffer(); $clearBuffer();
if ($this->next()->type === TokenType::ASTERISK) { if ($this->next()->type === TokenType::ASTERISK) {
$this->consume(); $this->consume();
@ -143,20 +156,20 @@ class Parser {
$clearBuffer(); $clearBuffer();
array_push($elms, $links); array_push($elms, $links);
} else { } else {
$buffer .= $this->consume()->data; $buffer .= self::StripBackslashes($this->consume()->data);
continue; continue;
} }
continue; continue;
} elseif ($this->current()->type === TokenType::BANG) { } elseif ($this->current()->type === TokenType::BANG) {
$bang = $this->consume(); $bang = $this->consume();
if ($this->current()->type !== TokenType::LBRACKET) { if ($this->current()->type !== TokenType::LBRACKET) {
$buffer .= $this->consume()->data; $buffer .= self::StripBackslashes($this->consume()->data);
continue; continue;
} }
$lbracket = $this->consume(); $lbracket = $this->consume();
$alt = ""; $alt = "";
while ($this->current()->type !== TokenType::RBRACKET && $this->current()->type !== TokenType::EOL) while ($this->current()->type !== TokenType::RBRACKET && $this->current()->type !== TokenType::EOL)
$alt .= $this->consume()->data; $alt .= self::StripBackslashes($this->consume()->data);
if ($this->current()->type !== TokenType::RBRACKET || $this->next()->type !== TokenType::LPAREN) { if ($this->current()->type !== TokenType::RBRACKET || $this->next()->type !== TokenType::LPAREN) {
$buffer .= "!"; $buffer .= "!";
@ -182,7 +195,7 @@ class Parser {
array_push($elms, $elm); array_push($elms, $elm);
continue; continue;
} else } else
$buffer .= $this->consume()->data; $buffer .= self::StripBackslashes($this->consume()->data);
} }
if (strlen($buffer) > 0) if (strlen($buffer) > 0)
array_push($elms, $this->document->createTextNode($buffer)); array_push($elms, $this->document->createTextNode($buffer));
@ -285,7 +298,7 @@ class Parser {
while (!($this->current()->type === TokenType::BACKTICK && while (!($this->current()->type === TokenType::BACKTICK &&
$this->next()->type === TokenType::BACKTICK && $this->next()->type === TokenType::BACKTICK &&
$this->peek(2)->type === TokenType::BACKTICK) && $this->current()->type !== TokenType::EOF) { $this->peek(2)->type === TokenType::BACKTICK) && $this->current()->type !== TokenType::EOF) {
$buffer .= $this->consume()->data; $buffer .= self::StripBackslashes($this->consume()->data);
} }
if ($this->current()->type !== TokenType::EOF) { if ($this->current()->type !== TokenType::EOF) {
$this->consume(); $this->consume();
@ -412,6 +425,12 @@ class Parser {
} }
} }
public function debug() : void {
echo "<pre>";
print_r($this->tokenStream);
echo "</pre>";
}
public function parse() : DOMDocument { public function parse() : DOMDocument {
while ($this->current()->type !== TokenType::EOF) { while ($this->current()->type !== TokenType::EOF) {
switch($this->current()->type) { switch($this->current()->type) {

@ -3,22 +3,23 @@
namespace parkdown; namespace parkdown;
enum TokenType { enum TokenType {
case HASH ; case HASH ;
case ASTERISK; case ASTERISK ;
case TEXT ; case TEXT ;
case DOT ; case DOT ;
case MINUS ; case MINUS ;
case NUMBER ; case NUMBER ;
case EOL ; case EOL ;
case EOF ; case EOF ;
case BACKTICK; case BACKTICK ;
case LBRACKET; case LBRACKET ;
case RBRACKET; case RBRACKET ;
case LPAREN ; case LPAREN ;
case RPAREN ; case RPAREN ;
case BANG ; case BANG ;
case COLON ; case COLON ;
case PIPE ; case BACKSLASH;
case PIPE ;
} }
class Token { class Token {

Loading…
Cancel
Save