@@ -45,7 +45,7 @@ discard block  | 
                                                    ||
| 45 | 45 | $this->source[] = $ref;  | 
                                                        
| 46 | 46 | $this->baseType = $tag;  | 
                                                        
| 47 | 47 | self::$var++;  | 
                                                        
| 48 | - $this->varname = "\$dynhtml" . self::$var;  | 
                                                        |
| 48 | + $this->varname = "\$dynhtml".self::$var;  | 
                                                        |
| 49 | 49 | }  | 
                                                        
| 50 | 50 | |
| 51 | 51 | function render(int $indent = 0, bool $minify = false): string  | 
                                                        
@@ -58,16 +58,16 @@ discard block  | 
                                                    ||
| 58 | 58 | 'content' => $this->content,  | 
                                                        
| 59 | 59 | ]);  | 
                                                        
| 60 | 60 | $out =  | 
                                                        
| 61 | - '<?php ' .  | 
                                                        |
| 62 | - $this->varname .  | 
                                                        |
| 63 | -      "=$data; echo Hamle\\Tag\\DynHtml::toStTag(" . | 
                                                        |
| 64 | - $this->varname .  | 
                                                        |
| 61 | + '<?php '.  | 
                                                        |
| 62 | + $this->varname.  | 
                                                        |
| 63 | +      "=$data; echo Hamle\\Tag\\DynHtml::toStTag(". | 
                                                        |
| 64 | + $this->varname.  | 
                                                        |
| 65 | 65 | ",\$form).";  | 
                                                        
| 66 | - $out .= "implode(\"\\n\"," . $this->varname . "['content']).";  | 
                                                        |
| 66 | + $out .= "implode(\"\\n\",".$this->varname."['content']).";  | 
                                                        |
| 67 | 67 | $out .=  | 
                                                        
| 68 | -      'Hamle\\Tag\\DynHtml::toEnTag(' . | 
                                                        |
| 69 | - $this->varname .  | 
                                                        |
| 70 | - ",\$form)?>" .  | 
                                                        |
| 68 | +      'Hamle\\Tag\\DynHtml::toEnTag('. | 
                                                        |
| 69 | + $this->varname.  | 
                                                        |
| 70 | + ",\$form)?>".  | 
                                                        |
| 71 | 71 | ($minify ? '' : "\n");  | 
                                                        
| 72 | 72 | return $out;  | 
                                                        
| 73 | 73 | }  | 
                                                        
@@ -84,7 +84,7 @@ discard block  | 
                                                    ||
| 84 | 84 | ->getField($source)  | 
                                                        
| 85 | 85 | ->getDynamicAtt($d['base'], $d['opt'], $d['type'], $d['content']);  | 
                                                        
| 86 | 86 | }  | 
                                                        
| 87 | - $out = '<' . $d['type'] . ' ';  | 
                                                        |
| 87 | + $out = '<'.$d['type'].' ';  | 
                                                        |
| 88 | 88 |      foreach ($d['opt'] as $k => $v) { | 
                                                        
| 89 | 89 |        if (is_array($v)) { | 
                                                        
| 90 | 90 |          foreach ($v as $k2 => $v2) { | 
                                                        
@@ -92,15 +92,15 @@ discard block  | 
                                                    ||
| 92 | 92 | /**  | 
                                                        
| 93 | 93 | * @psalm-suppress UndefinedMethod  | 
                                                        
| 94 | 94 | */  | 
                                                        
| 95 | -            $v[$k2] = eval('return ' . $v[$k2]->toPHP() . ';'); | 
                                                        |
| 95 | +            $v[$k2] = eval('return '.$v[$k2]->toPHP().';'); | 
                                                        |
| 96 | 96 | }  | 
                                                        
| 97 | 97 | }  | 
                                                        
| 98 | 98 |          $v = implode(' ', $v); | 
                                                        
| 99 | 99 | }  | 
                                                        
| 100 | 100 |        if ($v instanceof H\Text) { | 
                                                        
| 101 | -        $v = eval('return ' . $v->toPHP() . ';'); | 
                                                        |
| 101 | +        $v = eval('return '.$v->toPHP().';'); | 
                                                        |
| 102 | 102 | }  | 
                                                        
| 103 | - $out .= $k . "=\"" . htmlspecialchars($v) . "\" ";  | 
                                                        |
| 103 | + $out .= $k."=\"".htmlspecialchars($v)."\" ";  | 
                                                        |
| 104 | 104 | }  | 
                                                        
| 105 | 105 | $out .= in_array($d['type'], self::$selfCloseTags) ? '/>' : '>';  | 
                                                        
| 106 | 106 | return $out;  | 
                                                        
@@ -110,6 +110,6 @@ discard block  | 
                                                    ||
| 110 | 110 |    { | 
                                                        
| 111 | 111 | return in_array($d['type'], self::$selfCloseTags)  | 
                                                        
| 112 | 112 | ? ''  | 
                                                        
| 113 | - : '</' . $d['type'] . '>';  | 
                                                        |
| 113 | + : '</'.$d['type'].'>';  | 
                                                        |
| 114 | 114 | }  | 
                                                        
| 115 | 115 | }  | 
                                                        
@@ -84,7 +84,7 @@ discard block  | 
                                                    ||
| 84 | 84 | function renderStTag(): string  | 
                                                        
| 85 | 85 |    { | 
                                                        
| 86 | 86 | $close = in_array($this->type, self::$selfCloseTags) ? ' />' : '>';  | 
                                                        
| 87 | -    return "<{$this->type}" . $this->optToTags() . $close; | 
                                                        |
| 87 | +    return "<{$this->type}".$this->optToTags().$close; | 
                                                        |
| 88 | 88 | }  | 
                                                        
| 89 | 89 | |
| 90 | 90 | function renderEnTag(): string  | 
                                                        
@@ -114,7 +114,7 @@ discard block  | 
                                                    ||
| 114 | 114 | $v = new H\Text($v ?? '');  | 
                                                        
| 115 | 115 | }  | 
                                                        
| 116 | 116 | $k = new H\Text($k);  | 
                                                        
| 117 | - $out[] = ' ' . $k->toHTML() . "=\"" . $v->toHTMLAtt() . "\"";  | 
                                                        |
| 117 | + $out[] = ' '.$k->toHTML()."=\"".$v->toHTMLAtt()."\"";  | 
                                                        |
| 118 | 118 | }  | 
                                                        
| 119 | 119 |      return implode('', $out); | 
                                                        
| 120 | 120 | }  | 
                                                        
@@ -50,7 +50,7 @@ discard block  | 
                                                    ||
| 50 | 50 | function __construct(string $tag, H\Tag $parentTag = null)  | 
                                                        
| 51 | 51 |    { | 
                                                        
| 52 | 52 | parent::__construct();  | 
                                                        
| 53 | - $this->o = "\$o" . self::$instCount++;  | 
                                                        |
| 53 | + $this->o = "\$o".self::$instCount++;  | 
                                                        |
| 54 | 54 | $this->type = strtolower($tag);  | 
                                                        
| 55 | 55 | $this->var = '';  | 
                                                        
| 56 | 56 |      if ($parentTag && $this->type == 'else') { | 
                                                        
@@ -70,15 +70,15 @@ discard block  | 
                                                    ||
| 70 | 70 | |
| 71 | 71 | function renderStTag(): string  | 
                                                        
| 72 | 72 |    { | 
                                                        
| 73 | - $out = '<' . '?php ';  | 
                                                        |
| 73 | + $out = '<'.'?php ';  | 
                                                        |
| 74 | 74 | $scopeName = '';  | 
                                                        
| 75 | 75 |      if ($this->type === 'if') { | 
                                                        
| 76 | 76 | $hsvcomp = new H\Text\Comparison($this->var);  | 
                                                        
| 77 | -      $out .= 'if(' . $hsvcomp->toPHP() . ') {'; | 
                                                        |
| 78 | - return $out . "\n?>";  | 
                                                        |
| 77 | +      $out .= 'if('.$hsvcomp->toPHP().') {'; | 
                                                        |
| 78 | + return $out."\n?>";  | 
                                                        |
| 79 | 79 |      } elseif ($this->type === 'else') { | 
                                                        
| 80 | 80 | $out .= '/* else */';  | 
                                                        
| 81 | - return $out . "\n?>";  | 
                                                        |
| 81 | + return $out."\n?>";  | 
                                                        |
| 82 | 82 | }  | 
                                                        
| 83 | 83 | /** @var H\Text|null $hsv */  | 
                                                        
| 84 | 84 | $hsv = null;  | 
                                                        
@@ -94,7 +94,7 @@ discard block  | 
                                                    ||
| 94 | 94 |      switch ($this->type) { | 
                                                        
| 95 | 95 | case 'each':  | 
                                                        
| 96 | 96 |          if ($hsv) { | 
                                                        
| 97 | -          $out .= 'foreach(' . $hsv->toPHP() . " as {$this->o}) { \n"; | 
                                                        |
| 97 | +          $out .= 'foreach('.$hsv->toPHP()." as {$this->o}) { \n"; | 
                                                        |
| 98 | 98 |          } else { | 
                                                        
| 99 | 99 |            $out .= "foreach(Hamle\\Scope::get() as {$this->o}) { \n"; | 
                                                        
| 100 | 100 | }  | 
                                                        
@@ -108,12 +108,12 @@ discard block  | 
                                                    ||
| 108 | 108 | }  | 
                                                        
| 109 | 109 |          if ($scopeName) { | 
                                                        
| 110 | 110 | $out .=  | 
                                                        
| 111 | -            'Hamle\\Scope::add(' . $hsv->toPHP() . ", \"$scopeName\");\n;"; | 
                                                        |
| 111 | +            'Hamle\\Scope::add('.$hsv->toPHP().", \"$scopeName\");\n;"; | 
                                                        |
| 112 | 112 |          } else { | 
                                                        
| 113 | 113 | $out .=  | 
                                                        
| 114 | -            "if(({$this->o} = " . | 
                                                        |
| 115 | - $hsv->toPHP() .  | 
                                                        |
| 116 | - ') && ' .  | 
                                                        |
| 114 | +            "if(({$this->o} = ". | 
                                                        |
| 115 | + $hsv->toPHP().  | 
                                                        |
| 116 | + ') && '.  | 
                                                        |
| 117 | 117 |              "{$this->o}->valid()) {\n"; | 
                                                        
| 118 | 118 |            $out .= "Hamle\\Scope::add({$this->o});\n;"; | 
                                                        
| 119 | 119 | }  | 
                                                        
@@ -128,7 +128,7 @@ discard block  | 
                                                    ||
| 128 | 128 | $fn = $file[0] === '#' ? 'includeFragment' : 'includeFile';  | 
                                                        
| 129 | 129 |          $out .= "echo Hamle\\Run::$fn({$hsv->toPHP()});"; | 
                                                        
| 130 | 130 | }  | 
                                                        
| 131 | - return $out . "\n?>";  | 
                                                        |
| 131 | + return $out."\n?>";  | 
                                                        |
| 132 | 132 | }  | 
                                                        
| 133 | 133 | |
| 134 | 134 | /**  | 
                                                        
@@ -141,7 +141,7 @@ discard block  | 
                                                    ||
| 141 | 141 | |
| 142 | 142 | function renderEnTag(): string  | 
                                                        
| 143 | 143 |    { | 
                                                        
| 144 | - $out = '<' . '?php ';  | 
                                                        |
| 144 | + $out = '<'.'?php ';  | 
                                                        |
| 145 | 145 |      switch ($this->type) { | 
                                                        
| 146 | 146 | case 'each':  | 
                                                        
| 147 | 147 | $out .= 'Hamle\\Scope::done(); ';  | 
                                                        
@@ -166,7 +166,7 @@ discard block  | 
                                                    ||
| 166 | 166 |      if ($this->else) { | 
                                                        
| 167 | 167 |        $out .= 'else{'; | 
                                                        
| 168 | 168 | }  | 
                                                        
| 169 | - return $out . "\n?>";  | 
                                                        |
| 169 | + return $out."\n?>";  | 
                                                        |
| 170 | 170 | }  | 
                                                        
| 171 | 171 | |
| 172 | 172 | function render(int $indent = 0, bool $minify = false): string  | 
                                                        
@@ -53,278 +53,3 @@  | 
                                                    ||
| 53 | 53 | */  | 
                                                        
| 54 | 54 | |
| 55 | 55 | const REGEX_PARSE_LINE = <<<'ENDREGEX'  | 
                                                        
| 56 | -  /^(\s*)(?:(?:([a-zA-Z0-9-]*)((?:[\.#!][\w\-\_]+)*)(\[(?:(?:\{\$[^\}]+\})?[^\\\]{]*?(?:\\.)*?(?:{[^\$])*?)+\])?)|([_\/]{1,3})|([\|:\$]\w+)|({?\$[^}]+}?)|)(?: (.*))?$/ | 
                                                        |
| 57 | - ENDREGEX;  | 
                                                        |
| 58 | -  | 
                                                        |
| 59 | - /**  | 
                                                        |
| 60 | - * @var int Current Line Number  | 
                                                        |
| 61 | - */  | 
                                                        |
| 62 | - protected int $lineNo = 0;  | 
                                                        |
| 63 | - /**  | 
                                                        |
| 64 | - * @var int Total Lines in File  | 
                                                        |
| 65 | - */  | 
                                                        |
| 66 | - protected int $lineCount = 0;  | 
                                                        |
| 67 | -  | 
                                                        |
| 68 | - function __construct()  | 
                                                        |
| 69 | -  { | 
                                                        |
| 70 | - $this->init();  | 
                                                        |
| 71 | - }  | 
                                                        |
| 72 | -  | 
                                                        |
| 73 | - /**  | 
                                                        |
| 74 | - * Clear Lines, and Line Number, so if output is  | 
                                                        |
| 75 | - * called, no output will be produced  | 
                                                        |
| 76 | - */  | 
                                                        |
| 77 | - protected function init():void  | 
                                                        |
| 78 | -  { | 
                                                        |
| 79 | - $this->lines = [];  | 
                                                        |
| 80 | - $this->lineNo = 0;  | 
                                                        |
| 81 | - $this->lineCount = 0;  | 
                                                        |
| 82 | - $this->root = [];  | 
                                                        |
| 83 | - }  | 
                                                        |
| 84 | -  | 
                                                        |
| 85 | - protected function loadLines(string $s):void  | 
                                                        |
| 86 | -  { | 
                                                        |
| 87 | -    $this->lines = explode("\n", str_replace("\r", '', $s)); | 
                                                        |
| 88 | - $this->lineCount = count($this->lines);  | 
                                                        |
| 89 | - $this->lineNo = 0;  | 
                                                        |
| 90 | - }  | 
                                                        |
| 91 | -  | 
                                                        |
| 92 | - function parseFilter(ParseFilter $filter):void  | 
                                                        |
| 93 | -  { | 
                                                        |
| 94 | -    foreach ($this->root as $k => $tag) { | 
                                                        |
| 95 | - $this->root[$k] = $filter->filterTag($tag);  | 
                                                        |
| 96 | - }  | 
                                                        |
| 97 | - }  | 
                                                        |
| 98 | -  | 
                                                        |
| 99 | - function parseSnip(string $s):void  | 
                                                        |
| 100 | -  { | 
                                                        |
| 101 | - //save root tags  | 
                                                        |
| 102 | - /** @var Tag[] $roots */  | 
                                                        |
| 103 | - $roots = $this->root;  | 
                                                        |
| 104 | - $this->root = [];  | 
                                                        |
| 105 | - $this->loadLines($s);  | 
                                                        |
| 106 | - $this->procLines();  | 
                                                        |
| 107 | - $this->root = array_merge($roots, $this->root);  | 
                                                        |
| 108 | - }  | 
                                                        |
| 109 | -  | 
                                                        |
| 110 | - function applySnip():void  | 
                                                        |
| 111 | -  { | 
                                                        |
| 112 | - /** @var Tag\Snippet[] $fwdSnip */  | 
                                                        |
| 113 | - $fwdSnip = [];  | 
                                                        |
| 114 | - /** @var Tag\Snippet[] $revSnip */  | 
                                                        |
| 115 | - $revSnip = [];  | 
                                                        |
| 116 | - /** @var Tag[] $roots */  | 
                                                        |
| 117 | - $roots = [];  | 
                                                        |
| 118 | -    foreach ($this->root as $snip) { | 
                                                        |
| 119 | -      if ($snip instanceof Tag\Snippet) { | 
                                                        |
| 120 | -        if ($snip->getType() == 'append') { | 
                                                        |
| 121 | - array_unshift($revSnip, $snip);  | 
                                                        |
| 122 | -        } else { | 
                                                        |
| 123 | - $fwdSnip[] = $snip;  | 
                                                        |
| 124 | - }  | 
                                                        |
| 125 | -      } else { | 
                                                        |
| 126 | - $roots[] = $snip;  | 
                                                        |
| 127 | - }  | 
                                                        |
| 128 | - }  | 
                                                        |
| 129 | -    foreach ($fwdSnip as $snip) { | 
                                                        |
| 130 | -      foreach ($roots as $root) { | 
                                                        |
| 131 | - $snip->apply($root);  | 
                                                        |
| 132 | - }  | 
                                                        |
| 133 | - }  | 
                                                        |
| 134 | -    foreach ($revSnip as $snip) { | 
                                                        |
| 135 | -      foreach ($roots as $root) { | 
                                                        |
| 136 | - $snip->apply($root);  | 
                                                        |
| 137 | - }  | 
                                                        |
| 138 | - }  | 
                                                        |
| 139 | - $this->root = $roots;  | 
                                                        |
| 140 | - }  | 
                                                        |
| 141 | -  | 
                                                        |
| 142 | - /**  | 
                                                        |
| 143 | - * Parse HAMLE template, from a string  | 
                                                        |
| 144 | - * @param string $s String to parse  | 
                                                        |
| 145 | - */  | 
                                                        |
| 146 | - function str($s):void  | 
                                                        |
| 147 | -  { | 
                                                        |
| 148 | - $this->init();  | 
                                                        |
| 149 | - $this->loadLines($s);  | 
                                                        |
| 150 | - $this->procLines();  | 
                                                        |
| 151 | - }  | 
                                                        |
| 152 | -  | 
                                                        |
| 153 | - function procLines():void  | 
                                                        |
| 154 | -  { | 
                                                        |
| 155 | - /* @var $heir Tag[] Tag Heirachy Array */  | 
                                                        |
| 156 | - $heir = [];  | 
                                                        |
| 157 | -    while ($this->lineNo < $this->lineCount) { | 
                                                        |
| 158 | - $line = $this->lines[$this->lineNo];  | 
                                                        |
| 159 | -      if (trim($line)) { | 
                                                        |
| 160 | -        if (preg_match(self::REGEX_PARSE_LINE, $line, $m)) { | 
                                                        |
| 161 | -          if (false !== strpos($m[1], "\t")) { | 
                                                        |
| 162 | - throw new ParseError(  | 
                                                        |
| 163 | - 'Tabs are not supported in templates at this time',  | 
                                                        |
| 164 | - );  | 
                                                        |
| 165 | - }  | 
                                                        |
| 166 | - $indent = strlen($m[1]);  | 
                                                        |
| 167 | - $tag = isset($m[2]) ? ($tag = $m[2]) : '';  | 
                                                        |
| 168 | - $classid = isset($m[3]) ? $m[3] : '';  | 
                                                        |
| 169 | - $params = str_replace(  | 
                                                        |
| 170 | - ['\[', '\]', '\\&'],  | 
                                                        |
| 171 | - ['[', ']', '%26'],  | 
                                                        |
| 172 | - isset($m[4]) ? $m[4] : '',  | 
                                                        |
| 173 | - );  | 
                                                        |
| 174 | - $textcode = isset($m[5]) ? $m[5] : '';  | 
                                                        |
| 175 | - $text = isset($m[8]) ? $m[8] : '';  | 
                                                        |
| 176 | - $code = isset($m[6]) ? $m[6] : '';  | 
                                                        |
| 177 | - $i = self::indentLevel($indent);  | 
                                                        |
| 178 | - unset($m[0]);  | 
                                                        |
| 179 | -          switch (strlen($code) ? $code[0] : ($textcode ? $textcode : '')) { | 
                                                        |
| 180 | - case '|': //Control Tag  | 
                                                        |
| 181 | -              if ($code == '|snippet') { | 
                                                        |
| 182 | - $hTag = new Tag\Snippet($text);  | 
                                                        |
| 183 | -              } elseif ($code == '|form') { | 
                                                        |
| 184 | - $hTag = new Tag\Form($text);  | 
                                                        |
| 185 | -              } elseif ($code == '|formhint') { | 
                                                        |
| 186 | - $hTag = new Tag\FormHint();  | 
                                                        |
| 187 | -              } elseif ($code == '|else') { | 
                                                        |
| 188 | - $hTag = new Tag\Control(substr($code, 1), $heir[$i - 1]);  | 
                                                        |
| 189 | - $hTag->setVar($text);  | 
                                                        |
| 190 | -              } else { | 
                                                        |
| 191 | - $hTag = new Tag\Control(substr($code, 1));  | 
                                                        |
| 192 | - $hTag->setVar($text);  | 
                                                        |
| 193 | - }  | 
                                                        |
| 194 | - break;  | 
                                                        |
| 195 | - case ':': //Filter Tag  | 
                                                        |
| 196 | - $hTag = new Tag\Filter(substr($code, 1));  | 
                                                        |
| 197 | - $hTag->addContent($text, Text::TOKEN_CODE);  | 
                                                        |
| 198 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 199 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 200 | - }  | 
                                                        |
| 201 | - break;  | 
                                                        |
| 202 | - case '_': //String Tag  | 
                                                        |
| 203 | - case '__': //Unescape String Tag  | 
                                                        |
| 204 | - case '___': //Unescape String Tag (with unescaped vars)  | 
                                                        |
| 205 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 206 | - $hTag->addContent($text);  | 
                                                        |
| 207 | - break;  | 
                                                        |
| 208 | - case '___': //Unescape String Tag  | 
                                                        |
| 209 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 210 | - $hTag->addContent($text);  | 
                                                        |
| 211 | - break;  | 
                                                        |
| 212 | - case '/': // HTML Comment  | 
                                                        |
| 213 | - case '//': // Non Printed Comment  | 
                                                        |
| 214 | - $hTag = new Tag\Comment($textcode);  | 
                                                        |
| 215 | - $hTag->addContent($text);  | 
                                                        |
| 216 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 217 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 218 | - }  | 
                                                        |
| 219 | - break;  | 
                                                        |
| 220 | - default:  | 
                                                        |
| 221 | - $attr = [];  | 
                                                        |
| 222 | -              if (isset($params[0]) && $params[0] == '[') { | 
                                                        |
| 223 | - $param = substr($params, 1, -1);  | 
                                                        |
| 224 | - $param = str_replace(['+', '\\&'], ['%2B', '%26'], $param);  | 
                                                        |
| 225 | - $attr = $this->parseQueryString($param);  | 
                                                        |
| 226 | - }  | 
                                                        |
| 227 | - $class = [];  | 
                                                        |
| 228 | - $id = '';  | 
                                                        |
| 229 | - $ref = '';  | 
                                                        |
| 230 | -              preg_match_all('/[#\.!][a-zA-Z0-9\-\_]+/m', $classid, $cid); | 
                                                        |
| 231 | -              if (isset($cid[0])) { | 
                                                        |
| 232 | -                foreach ($cid[0] as $s) { | 
                                                        |
| 233 | -                  if ($s[0] == '#') { | 
                                                        |
| 234 | - $id = substr($s, 1);  | 
                                                        |
| 235 | - }  | 
                                                        |
| 236 | -                  if ($s[0] == '.') { | 
                                                        |
| 237 | - $class[] = substr($s, 1);  | 
                                                        |
| 238 | - }  | 
                                                        |
| 239 | -                  if ($s[0] == '!') { | 
                                                        |
| 240 | - $ref = substr($s, 1);  | 
                                                        |
| 241 | - }  | 
                                                        |
| 242 | - }  | 
                                                        |
| 243 | - }  | 
                                                        |
| 244 | -              if ($ref) { | 
                                                        |
| 245 | - $hTag = new Tag\DynHtml($tag, $class, $attr, $id, $ref);  | 
                                                        |
| 246 | -              } else { | 
                                                        |
| 247 | - $hTag = new Tag\Html($tag, $class, $attr, $id);  | 
                                                        |
| 248 | - }  | 
                                                        |
| 249 | - $hTag->addContent($text);  | 
                                                        |
| 250 | - break;  | 
                                                        |
| 251 | - }  | 
                                                        |
| 252 | - $heir[$i] = $hTag;  | 
                                                        |
| 253 | -          if ($i > 0) { | 
                                                        |
| 254 | - $heir[$i - 1]->addChild($hTag);  | 
                                                        |
| 255 | -          } else { | 
                                                        |
| 256 | - $this->root[] = $hTag;  | 
                                                        |
| 257 | - }  | 
                                                        |
| 258 | -        } else { | 
                                                        |
| 259 | - throw new ParseError(  | 
                                                        |
| 260 | -            "Unable to parse line {$this->lineNo}\n\"$line\"/" . | 
                                                        |
| 261 | - preg_last_error(),  | 
                                                        |
| 262 | - );  | 
                                                        |
| 263 | - }  | 
                                                        |
| 264 | - }  | 
                                                        |
| 265 | - $this->lineNo++;  | 
                                                        |
| 266 | - }  | 
                                                        |
| 267 | - }  | 
                                                        |
| 268 | -  | 
                                                        |
| 269 | - function parseQueryString(string $qs):array  | 
                                                        |
| 270 | -  { | 
                                                        |
| 271 | - $out = [];  | 
                                                        |
| 272 | -    foreach (explode('&', $qs) as $s) { | 
                                                        |
| 273 | -      $kv = explode('=', $s, 2); | 
                                                        |
| 274 | - $out[urldecode($kv[0])] = isset($kv[1]) ? urldecode($kv[1]) : null;  | 
                                                        |
| 275 | - }  | 
                                                        |
| 276 | - return $out;  | 
                                                        |
| 277 | - }  | 
                                                        |
| 278 | -  | 
                                                        |
| 279 | - function output(bool $minify = false):string  | 
                                                        |
| 280 | -  { | 
                                                        |
| 281 | - $out = "<?php\nuse Seufert\\Hamle;\n?>";  | 
                                                        |
| 282 | -    foreach ($this->root as $tag) { | 
                                                        |
| 283 | - $out .= $tag->render(0, $minify);  | 
                                                        |
| 284 | - }  | 
                                                        |
| 285 | - return $out;  | 
                                                        |
| 286 | - }  | 
                                                        |
| 287 | -  | 
                                                        |
| 288 | - function consumeBlock(int $indent):array  | 
                                                        |
| 289 | -  { | 
                                                        |
| 290 | - $out = [];  | 
                                                        |
| 291 | - $m = [];  | 
                                                        |
| 292 | - while (  | 
                                                        |
| 293 | - $this->lineNo + 1 < $this->lineCount &&  | 
                                                        |
| 294 | - (!trim($this->lines[$this->lineNo + 1]) ||  | 
                                                        |
| 295 | - preg_match(  | 
                                                        |
| 296 | -          '/^(\s){' . $indent . '}((\s)+[^\s].*)$/', | 
                                                        |
| 297 | - $this->lines[$this->lineNo + 1],  | 
                                                        |
| 298 | - $m,  | 
                                                        |
| 299 | - ))  | 
                                                        |
| 300 | -    ) { | 
                                                        |
| 301 | -      if (trim($this->lines[$this->lineNo + 1])) { | 
                                                        |
| 302 | - $out[] = $m[2];  | 
                                                        |
| 303 | - }  | 
                                                        |
| 304 | - $this->lineNo++;  | 
                                                        |
| 305 | - }  | 
                                                        |
| 306 | - return $out;  | 
                                                        |
| 307 | - }  | 
                                                        |
| 308 | -  | 
                                                        |
| 309 | - function indentLevel(int $indent):int  | 
                                                        |
| 310 | -  { | 
                                                        |
| 311 | -    if (!count($this->indents)) { | 
                                                        |
| 312 | - $this->indents = [0 => $indent];  | 
                                                        |
| 313 | - // Key = indent level, Value = Depth in spaces  | 
                                                        |
| 314 | - return 0;  | 
                                                        |
| 315 | - }  | 
                                                        |
| 316 | -    foreach ($this->indents as $k => $v) { | 
                                                        |
| 317 | -      if ($v == $indent) { | 
                                                        |
| 318 | - $this->indents = array_slice($this->indents, 0, 1 + (int) $k );  | 
                                                        |
| 319 | - return $k;  | 
                                                        |
| 320 | - }  | 
                                                        |
| 321 | - }  | 
                                                        |
| 322 | - $this->indents[] = $indent;  | 
                                                        |
| 323 | - return max(array_keys($this->indents));  | 
                                                        |
| 324 | - }  | 
                                                        |
| 325 | -  | 
                                                        |
| 326 | - function getLineNo():int  | 
                                                        |
| 327 | -  { | 
                                                        |
| 328 | - return $this->lineNo;  | 
                                                        |
| 329 | - }  | 
                                                        |
| 330 | -}  | 
                                                        |
@@ -53,278 +53,3 @@  | 
                                                    ||
| 53 | 53 | */  | 
                                                        
| 54 | 54 | |
| 55 | 55 | const REGEX_PARSE_LINE = <<<'ENDREGEX'  | 
                                                        
| 56 | -  /^(\s*)(?:(?:([a-zA-Z0-9-]*)((?:[\.#!][\w\-\_]+)*)(\[(?:(?:\{\$[^\}]+\})?[^\\\]{]*?(?:\\.)*?(?:{[^\$])*?)+\])?)|([_\/]{1,3})|([\|:\$]\w+)|({?\$[^}]+}?)|)(?: (.*))?$/ | 
                                                        |
| 57 | - ENDREGEX;  | 
                                                        |
| 58 | -  | 
                                                        |
| 59 | - /**  | 
                                                        |
| 60 | - * @var int Current Line Number  | 
                                                        |
| 61 | - */  | 
                                                        |
| 62 | - protected int $lineNo = 0;  | 
                                                        |
| 63 | - /**  | 
                                                        |
| 64 | - * @var int Total Lines in File  | 
                                                        |
| 65 | - */  | 
                                                        |
| 66 | - protected int $lineCount = 0;  | 
                                                        |
| 67 | -  | 
                                                        |
| 68 | - function __construct()  | 
                                                        |
| 69 | -  { | 
                                                        |
| 70 | - $this->init();  | 
                                                        |
| 71 | - }  | 
                                                        |
| 72 | -  | 
                                                        |
| 73 | - /**  | 
                                                        |
| 74 | - * Clear Lines, and Line Number, so if output is  | 
                                                        |
| 75 | - * called, no output will be produced  | 
                                                        |
| 76 | - */  | 
                                                        |
| 77 | - protected function init():void  | 
                                                        |
| 78 | -  { | 
                                                        |
| 79 | - $this->lines = [];  | 
                                                        |
| 80 | - $this->lineNo = 0;  | 
                                                        |
| 81 | - $this->lineCount = 0;  | 
                                                        |
| 82 | - $this->root = [];  | 
                                                        |
| 83 | - }  | 
                                                        |
| 84 | -  | 
                                                        |
| 85 | - protected function loadLines(string $s):void  | 
                                                        |
| 86 | -  { | 
                                                        |
| 87 | -    $this->lines = explode("\n", str_replace("\r", '', $s)); | 
                                                        |
| 88 | - $this->lineCount = count($this->lines);  | 
                                                        |
| 89 | - $this->lineNo = 0;  | 
                                                        |
| 90 | - }  | 
                                                        |
| 91 | -  | 
                                                        |
| 92 | - function parseFilter(ParseFilter $filter):void  | 
                                                        |
| 93 | -  { | 
                                                        |
| 94 | -    foreach ($this->root as $k => $tag) { | 
                                                        |
| 95 | - $this->root[$k] = $filter->filterTag($tag);  | 
                                                        |
| 96 | - }  | 
                                                        |
| 97 | - }  | 
                                                        |
| 98 | -  | 
                                                        |
| 99 | - function parseSnip(string $s):void  | 
                                                        |
| 100 | -  { | 
                                                        |
| 101 | - //save root tags  | 
                                                        |
| 102 | - /** @var Tag[] $roots */  | 
                                                        |
| 103 | - $roots = $this->root;  | 
                                                        |
| 104 | - $this->root = [];  | 
                                                        |
| 105 | - $this->loadLines($s);  | 
                                                        |
| 106 | - $this->procLines();  | 
                                                        |
| 107 | - $this->root = array_merge($roots, $this->root);  | 
                                                        |
| 108 | - }  | 
                                                        |
| 109 | -  | 
                                                        |
| 110 | - function applySnip():void  | 
                                                        |
| 111 | -  { | 
                                                        |
| 112 | - /** @var Tag\Snippet[] $fwdSnip */  | 
                                                        |
| 113 | - $fwdSnip = [];  | 
                                                        |
| 114 | - /** @var Tag\Snippet[] $revSnip */  | 
                                                        |
| 115 | - $revSnip = [];  | 
                                                        |
| 116 | - /** @var Tag[] $roots */  | 
                                                        |
| 117 | - $roots = [];  | 
                                                        |
| 118 | -    foreach ($this->root as $snip) { | 
                                                        |
| 119 | -      if ($snip instanceof Tag\Snippet) { | 
                                                        |
| 120 | -        if ($snip->getType() == 'append') { | 
                                                        |
| 121 | - array_unshift($revSnip, $snip);  | 
                                                        |
| 122 | -        } else { | 
                                                        |
| 123 | - $fwdSnip[] = $snip;  | 
                                                        |
| 124 | - }  | 
                                                        |
| 125 | -      } else { | 
                                                        |
| 126 | - $roots[] = $snip;  | 
                                                        |
| 127 | - }  | 
                                                        |
| 128 | - }  | 
                                                        |
| 129 | -    foreach ($fwdSnip as $snip) { | 
                                                        |
| 130 | -      foreach ($roots as $root) { | 
                                                        |
| 131 | - $snip->apply($root);  | 
                                                        |
| 132 | - }  | 
                                                        |
| 133 | - }  | 
                                                        |
| 134 | -    foreach ($revSnip as $snip) { | 
                                                        |
| 135 | -      foreach ($roots as $root) { | 
                                                        |
| 136 | - $snip->apply($root);  | 
                                                        |
| 137 | - }  | 
                                                        |
| 138 | - }  | 
                                                        |
| 139 | - $this->root = $roots;  | 
                                                        |
| 140 | - }  | 
                                                        |
| 141 | -  | 
                                                        |
| 142 | - /**  | 
                                                        |
| 143 | - * Parse HAMLE template, from a string  | 
                                                        |
| 144 | - * @param string $s String to parse  | 
                                                        |
| 145 | - */  | 
                                                        |
| 146 | - function str($s):void  | 
                                                        |
| 147 | -  { | 
                                                        |
| 148 | - $this->init();  | 
                                                        |
| 149 | - $this->loadLines($s);  | 
                                                        |
| 150 | - $this->procLines();  | 
                                                        |
| 151 | - }  | 
                                                        |
| 152 | -  | 
                                                        |
| 153 | - function procLines():void  | 
                                                        |
| 154 | -  { | 
                                                        |
| 155 | - /* @var $heir Tag[] Tag Heirachy Array */  | 
                                                        |
| 156 | - $heir = [];  | 
                                                        |
| 157 | -    while ($this->lineNo < $this->lineCount) { | 
                                                        |
| 158 | - $line = $this->lines[$this->lineNo];  | 
                                                        |
| 159 | -      if (trim($line)) { | 
                                                        |
| 160 | -        if (preg_match(self::REGEX_PARSE_LINE, $line, $m)) { | 
                                                        |
| 161 | -          if (false !== strpos($m[1], "\t")) { | 
                                                        |
| 162 | - throw new ParseError(  | 
                                                        |
| 163 | - 'Tabs are not supported in templates at this time',  | 
                                                        |
| 164 | - );  | 
                                                        |
| 165 | - }  | 
                                                        |
| 166 | - $indent = strlen($m[1]);  | 
                                                        |
| 167 | - $tag = isset($m[2]) ? ($tag = $m[2]) : '';  | 
                                                        |
| 168 | - $classid = isset($m[3]) ? $m[3] : '';  | 
                                                        |
| 169 | - $params = str_replace(  | 
                                                        |
| 170 | - ['\[', '\]', '\\&'],  | 
                                                        |
| 171 | - ['[', ']', '%26'],  | 
                                                        |
| 172 | - isset($m[4]) ? $m[4] : '',  | 
                                                        |
| 173 | - );  | 
                                                        |
| 174 | - $textcode = isset($m[5]) ? $m[5] : '';  | 
                                                        |
| 175 | - $text = isset($m[8]) ? $m[8] : '';  | 
                                                        |
| 176 | - $code = isset($m[6]) ? $m[6] : '';  | 
                                                        |
| 177 | - $i = self::indentLevel($indent);  | 
                                                        |
| 178 | - unset($m[0]);  | 
                                                        |
| 179 | -          switch (strlen($code) ? $code[0] : ($textcode ? $textcode : '')) { | 
                                                        |
| 180 | - case '|': //Control Tag  | 
                                                        |
| 181 | -              if ($code == '|snippet') { | 
                                                        |
| 182 | - $hTag = new Tag\Snippet($text);  | 
                                                        |
| 183 | -              } elseif ($code == '|form') { | 
                                                        |
| 184 | - $hTag = new Tag\Form($text);  | 
                                                        |
| 185 | -              } elseif ($code == '|formhint') { | 
                                                        |
| 186 | - $hTag = new Tag\FormHint();  | 
                                                        |
| 187 | -              } elseif ($code == '|else') { | 
                                                        |
| 188 | - $hTag = new Tag\Control(substr($code, 1), $heir[$i - 1]);  | 
                                                        |
| 189 | - $hTag->setVar($text);  | 
                                                        |
| 190 | -              } else { | 
                                                        |
| 191 | - $hTag = new Tag\Control(substr($code, 1));  | 
                                                        |
| 192 | - $hTag->setVar($text);  | 
                                                        |
| 193 | - }  | 
                                                        |
| 194 | - break;  | 
                                                        |
| 195 | - case ':': //Filter Tag  | 
                                                        |
| 196 | - $hTag = new Tag\Filter(substr($code, 1));  | 
                                                        |
| 197 | - $hTag->addContent($text, Text::TOKEN_CODE);  | 
                                                        |
| 198 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 199 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 200 | - }  | 
                                                        |
| 201 | - break;  | 
                                                        |
| 202 | - case '_': //String Tag  | 
                                                        |
| 203 | - case '__': //Unescape String Tag  | 
                                                        |
| 204 | - case '___': //Unescape String Tag (with unescaped vars)  | 
                                                        |
| 205 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 206 | - $hTag->addContent($text);  | 
                                                        |
| 207 | - break;  | 
                                                        |
| 208 | - case '___': //Unescape String Tag  | 
                                                        |
| 209 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 210 | - $hTag->addContent($text);  | 
                                                        |
| 211 | - break;  | 
                                                        |
| 212 | - case '/': // HTML Comment  | 
                                                        |
| 213 | - case '//': // Non Printed Comment  | 
                                                        |
| 214 | - $hTag = new Tag\Comment($textcode);  | 
                                                        |
| 215 | - $hTag->addContent($text);  | 
                                                        |
| 216 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 217 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 218 | - }  | 
                                                        |
| 219 | - break;  | 
                                                        |
| 220 | - default:  | 
                                                        |
| 221 | - $attr = [];  | 
                                                        |
| 222 | -              if (isset($params[0]) && $params[0] == '[') { | 
                                                        |
| 223 | - $param = substr($params, 1, -1);  | 
                                                        |
| 224 | - $param = str_replace(['+', '\\&'], ['%2B', '%26'], $param);  | 
                                                        |
| 225 | - $attr = $this->parseQueryString($param);  | 
                                                        |
| 226 | - }  | 
                                                        |
| 227 | - $class = [];  | 
                                                        |
| 228 | - $id = '';  | 
                                                        |
| 229 | - $ref = '';  | 
                                                        |
| 230 | -              preg_match_all('/[#\.!][a-zA-Z0-9\-\_]+/m', $classid, $cid); | 
                                                        |
| 231 | -              if (isset($cid[0])) { | 
                                                        |
| 232 | -                foreach ($cid[0] as $s) { | 
                                                        |
| 233 | -                  if ($s[0] == '#') { | 
                                                        |
| 234 | - $id = substr($s, 1);  | 
                                                        |
| 235 | - }  | 
                                                        |
| 236 | -                  if ($s[0] == '.') { | 
                                                        |
| 237 | - $class[] = substr($s, 1);  | 
                                                        |
| 238 | - }  | 
                                                        |
| 239 | -                  if ($s[0] == '!') { | 
                                                        |
| 240 | - $ref = substr($s, 1);  | 
                                                        |
| 241 | - }  | 
                                                        |
| 242 | - }  | 
                                                        |
| 243 | - }  | 
                                                        |
| 244 | -              if ($ref) { | 
                                                        |
| 245 | - $hTag = new Tag\DynHtml($tag, $class, $attr, $id, $ref);  | 
                                                        |
| 246 | -              } else { | 
                                                        |
| 247 | - $hTag = new Tag\Html($tag, $class, $attr, $id);  | 
                                                        |
| 248 | - }  | 
                                                        |
| 249 | - $hTag->addContent($text);  | 
                                                        |
| 250 | - break;  | 
                                                        |
| 251 | - }  | 
                                                        |
| 252 | - $heir[$i] = $hTag;  | 
                                                        |
| 253 | -          if ($i > 0) { | 
                                                        |
| 254 | - $heir[$i - 1]->addChild($hTag);  | 
                                                        |
| 255 | -          } else { | 
                                                        |
| 256 | - $this->root[] = $hTag;  | 
                                                        |
| 257 | - }  | 
                                                        |
| 258 | -        } else { | 
                                                        |
| 259 | - throw new ParseError(  | 
                                                        |
| 260 | -            "Unable to parse line {$this->lineNo}\n\"$line\"/" . | 
                                                        |
| 261 | - preg_last_error(),  | 
                                                        |
| 262 | - );  | 
                                                        |
| 263 | - }  | 
                                                        |
| 264 | - }  | 
                                                        |
| 265 | - $this->lineNo++;  | 
                                                        |
| 266 | - }  | 
                                                        |
| 267 | - }  | 
                                                        |
| 268 | -  | 
                                                        |
| 269 | - function parseQueryString(string $qs):array  | 
                                                        |
| 270 | -  { | 
                                                        |
| 271 | - $out = [];  | 
                                                        |
| 272 | -    foreach (explode('&', $qs) as $s) { | 
                                                        |
| 273 | -      $kv = explode('=', $s, 2); | 
                                                        |
| 274 | - $out[urldecode($kv[0])] = isset($kv[1]) ? urldecode($kv[1]) : null;  | 
                                                        |
| 275 | - }  | 
                                                        |
| 276 | - return $out;  | 
                                                        |
| 277 | - }  | 
                                                        |
| 278 | -  | 
                                                        |
| 279 | - function output(bool $minify = false):string  | 
                                                        |
| 280 | -  { | 
                                                        |
| 281 | - $out = "<?php\nuse Seufert\\Hamle;\n?>";  | 
                                                        |
| 282 | -    foreach ($this->root as $tag) { | 
                                                        |
| 283 | - $out .= $tag->render(0, $minify);  | 
                                                        |
| 284 | - }  | 
                                                        |
| 285 | - return $out;  | 
                                                        |
| 286 | - }  | 
                                                        |
| 287 | -  | 
                                                        |
| 288 | - function consumeBlock(int $indent):array  | 
                                                        |
| 289 | -  { | 
                                                        |
| 290 | - $out = [];  | 
                                                        |
| 291 | - $m = [];  | 
                                                        |
| 292 | - while (  | 
                                                        |
| 293 | - $this->lineNo + 1 < $this->lineCount &&  | 
                                                        |
| 294 | - (!trim($this->lines[$this->lineNo + 1]) ||  | 
                                                        |
| 295 | - preg_match(  | 
                                                        |
| 296 | -          '/^(\s){' . $indent . '}((\s)+[^\s].*)$/', | 
                                                        |
| 297 | - $this->lines[$this->lineNo + 1],  | 
                                                        |
| 298 | - $m,  | 
                                                        |
| 299 | - ))  | 
                                                        |
| 300 | -    ) { | 
                                                        |
| 301 | -      if (trim($this->lines[$this->lineNo + 1])) { | 
                                                        |
| 302 | - $out[] = $m[2];  | 
                                                        |
| 303 | - }  | 
                                                        |
| 304 | - $this->lineNo++;  | 
                                                        |
| 305 | - }  | 
                                                        |
| 306 | - return $out;  | 
                                                        |
| 307 | - }  | 
                                                        |
| 308 | -  | 
                                                        |
| 309 | - function indentLevel(int $indent):int  | 
                                                        |
| 310 | -  { | 
                                                        |
| 311 | -    if (!count($this->indents)) { | 
                                                        |
| 312 | - $this->indents = [0 => $indent];  | 
                                                        |
| 313 | - // Key = indent level, Value = Depth in spaces  | 
                                                        |
| 314 | - return 0;  | 
                                                        |
| 315 | - }  | 
                                                        |
| 316 | -    foreach ($this->indents as $k => $v) { | 
                                                        |
| 317 | -      if ($v == $indent) { | 
                                                        |
| 318 | - $this->indents = array_slice($this->indents, 0, 1 + (int) $k );  | 
                                                        |
| 319 | - return $k;  | 
                                                        |
| 320 | - }  | 
                                                        |
| 321 | - }  | 
                                                        |
| 322 | - $this->indents[] = $indent;  | 
                                                        |
| 323 | - return max(array_keys($this->indents));  | 
                                                        |
| 324 | - }  | 
                                                        |
| 325 | -  | 
                                                        |
| 326 | - function getLineNo():int  | 
                                                        |
| 327 | -  { | 
                                                        |
| 328 | - return $this->lineNo;  | 
                                                        |
| 329 | - }  | 
                                                        |
| 330 | -}  | 
                                                        |
@@ -53,278 +53,3 @@  | 
                                                    ||
| 53 | 53 | */  | 
                                                        
| 54 | 54 | |
| 55 | 55 | const REGEX_PARSE_LINE = <<<'ENDREGEX'  | 
                                                        
| 56 | -  /^(\s*)(?:(?:([a-zA-Z0-9-]*)((?:[\.#!][\w\-\_]+)*)(\[(?:(?:\{\$[^\}]+\})?[^\\\]{]*?(?:\\.)*?(?:{[^\$])*?)+\])?)|([_\/]{1,3})|([\|:\$]\w+)|({?\$[^}]+}?)|)(?: (.*))?$/ | 
                                                        |
| 57 | - ENDREGEX;  | 
                                                        |
| 58 | -  | 
                                                        |
| 59 | - /**  | 
                                                        |
| 60 | - * @var int Current Line Number  | 
                                                        |
| 61 | - */  | 
                                                        |
| 62 | - protected int $lineNo = 0;  | 
                                                        |
| 63 | - /**  | 
                                                        |
| 64 | - * @var int Total Lines in File  | 
                                                        |
| 65 | - */  | 
                                                        |
| 66 | - protected int $lineCount = 0;  | 
                                                        |
| 67 | -  | 
                                                        |
| 68 | - function __construct()  | 
                                                        |
| 69 | -  { | 
                                                        |
| 70 | - $this->init();  | 
                                                        |
| 71 | - }  | 
                                                        |
| 72 | -  | 
                                                        |
| 73 | - /**  | 
                                                        |
| 74 | - * Clear Lines, and Line Number, so if output is  | 
                                                        |
| 75 | - * called, no output will be produced  | 
                                                        |
| 76 | - */  | 
                                                        |
| 77 | - protected function init():void  | 
                                                        |
| 78 | -  { | 
                                                        |
| 79 | - $this->lines = [];  | 
                                                        |
| 80 | - $this->lineNo = 0;  | 
                                                        |
| 81 | - $this->lineCount = 0;  | 
                                                        |
| 82 | - $this->root = [];  | 
                                                        |
| 83 | - }  | 
                                                        |
| 84 | -  | 
                                                        |
| 85 | - protected function loadLines(string $s):void  | 
                                                        |
| 86 | -  { | 
                                                        |
| 87 | -    $this->lines = explode("\n", str_replace("\r", '', $s)); | 
                                                        |
| 88 | - $this->lineCount = count($this->lines);  | 
                                                        |
| 89 | - $this->lineNo = 0;  | 
                                                        |
| 90 | - }  | 
                                                        |
| 91 | -  | 
                                                        |
| 92 | - function parseFilter(ParseFilter $filter):void  | 
                                                        |
| 93 | -  { | 
                                                        |
| 94 | -    foreach ($this->root as $k => $tag) { | 
                                                        |
| 95 | - $this->root[$k] = $filter->filterTag($tag);  | 
                                                        |
| 96 | - }  | 
                                                        |
| 97 | - }  | 
                                                        |
| 98 | -  | 
                                                        |
| 99 | - function parseSnip(string $s):void  | 
                                                        |
| 100 | -  { | 
                                                        |
| 101 | - //save root tags  | 
                                                        |
| 102 | - /** @var Tag[] $roots */  | 
                                                        |
| 103 | - $roots = $this->root;  | 
                                                        |
| 104 | - $this->root = [];  | 
                                                        |
| 105 | - $this->loadLines($s);  | 
                                                        |
| 106 | - $this->procLines();  | 
                                                        |
| 107 | - $this->root = array_merge($roots, $this->root);  | 
                                                        |
| 108 | - }  | 
                                                        |
| 109 | -  | 
                                                        |
| 110 | - function applySnip():void  | 
                                                        |
| 111 | -  { | 
                                                        |
| 112 | - /** @var Tag\Snippet[] $fwdSnip */  | 
                                                        |
| 113 | - $fwdSnip = [];  | 
                                                        |
| 114 | - /** @var Tag\Snippet[] $revSnip */  | 
                                                        |
| 115 | - $revSnip = [];  | 
                                                        |
| 116 | - /** @var Tag[] $roots */  | 
                                                        |
| 117 | - $roots = [];  | 
                                                        |
| 118 | -    foreach ($this->root as $snip) { | 
                                                        |
| 119 | -      if ($snip instanceof Tag\Snippet) { | 
                                                        |
| 120 | -        if ($snip->getType() == 'append') { | 
                                                        |
| 121 | - array_unshift($revSnip, $snip);  | 
                                                        |
| 122 | -        } else { | 
                                                        |
| 123 | - $fwdSnip[] = $snip;  | 
                                                        |
| 124 | - }  | 
                                                        |
| 125 | -      } else { | 
                                                        |
| 126 | - $roots[] = $snip;  | 
                                                        |
| 127 | - }  | 
                                                        |
| 128 | - }  | 
                                                        |
| 129 | -    foreach ($fwdSnip as $snip) { | 
                                                        |
| 130 | -      foreach ($roots as $root) { | 
                                                        |
| 131 | - $snip->apply($root);  | 
                                                        |
| 132 | - }  | 
                                                        |
| 133 | - }  | 
                                                        |
| 134 | -    foreach ($revSnip as $snip) { | 
                                                        |
| 135 | -      foreach ($roots as $root) { | 
                                                        |
| 136 | - $snip->apply($root);  | 
                                                        |
| 137 | - }  | 
                                                        |
| 138 | - }  | 
                                                        |
| 139 | - $this->root = $roots;  | 
                                                        |
| 140 | - }  | 
                                                        |
| 141 | -  | 
                                                        |
| 142 | - /**  | 
                                                        |
| 143 | - * Parse HAMLE template, from a string  | 
                                                        |
| 144 | - * @param string $s String to parse  | 
                                                        |
| 145 | - */  | 
                                                        |
| 146 | - function str($s):void  | 
                                                        |
| 147 | -  { | 
                                                        |
| 148 | - $this->init();  | 
                                                        |
| 149 | - $this->loadLines($s);  | 
                                                        |
| 150 | - $this->procLines();  | 
                                                        |
| 151 | - }  | 
                                                        |
| 152 | -  | 
                                                        |
| 153 | - function procLines():void  | 
                                                        |
| 154 | -  { | 
                                                        |
| 155 | - /* @var $heir Tag[] Tag Heirachy Array */  | 
                                                        |
| 156 | - $heir = [];  | 
                                                        |
| 157 | -    while ($this->lineNo < $this->lineCount) { | 
                                                        |
| 158 | - $line = $this->lines[$this->lineNo];  | 
                                                        |
| 159 | -      if (trim($line)) { | 
                                                        |
| 160 | -        if (preg_match(self::REGEX_PARSE_LINE, $line, $m)) { | 
                                                        |
| 161 | -          if (false !== strpos($m[1], "\t")) { | 
                                                        |
| 162 | - throw new ParseError(  | 
                                                        |
| 163 | - 'Tabs are not supported in templates at this time',  | 
                                                        |
| 164 | - );  | 
                                                        |
| 165 | - }  | 
                                                        |
| 166 | - $indent = strlen($m[1]);  | 
                                                        |
| 167 | - $tag = isset($m[2]) ? ($tag = $m[2]) : '';  | 
                                                        |
| 168 | - $classid = isset($m[3]) ? $m[3] : '';  | 
                                                        |
| 169 | - $params = str_replace(  | 
                                                        |
| 170 | - ['\[', '\]', '\\&'],  | 
                                                        |
| 171 | - ['[', ']', '%26'],  | 
                                                        |
| 172 | - isset($m[4]) ? $m[4] : '',  | 
                                                        |
| 173 | - );  | 
                                                        |
| 174 | - $textcode = isset($m[5]) ? $m[5] : '';  | 
                                                        |
| 175 | - $text = isset($m[8]) ? $m[8] : '';  | 
                                                        |
| 176 | - $code = isset($m[6]) ? $m[6] : '';  | 
                                                        |
| 177 | - $i = self::indentLevel($indent);  | 
                                                        |
| 178 | - unset($m[0]);  | 
                                                        |
| 179 | -          switch (strlen($code) ? $code[0] : ($textcode ? $textcode : '')) { | 
                                                        |
| 180 | - case '|': //Control Tag  | 
                                                        |
| 181 | -              if ($code == '|snippet') { | 
                                                        |
| 182 | - $hTag = new Tag\Snippet($text);  | 
                                                        |
| 183 | -              } elseif ($code == '|form') { | 
                                                        |
| 184 | - $hTag = new Tag\Form($text);  | 
                                                        |
| 185 | -              } elseif ($code == '|formhint') { | 
                                                        |
| 186 | - $hTag = new Tag\FormHint();  | 
                                                        |
| 187 | -              } elseif ($code == '|else') { | 
                                                        |
| 188 | - $hTag = new Tag\Control(substr($code, 1), $heir[$i - 1]);  | 
                                                        |
| 189 | - $hTag->setVar($text);  | 
                                                        |
| 190 | -              } else { | 
                                                        |
| 191 | - $hTag = new Tag\Control(substr($code, 1));  | 
                                                        |
| 192 | - $hTag->setVar($text);  | 
                                                        |
| 193 | - }  | 
                                                        |
| 194 | - break;  | 
                                                        |
| 195 | - case ':': //Filter Tag  | 
                                                        |
| 196 | - $hTag = new Tag\Filter(substr($code, 1));  | 
                                                        |
| 197 | - $hTag->addContent($text, Text::TOKEN_CODE);  | 
                                                        |
| 198 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 199 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 200 | - }  | 
                                                        |
| 201 | - break;  | 
                                                        |
| 202 | - case '_': //String Tag  | 
                                                        |
| 203 | - case '__': //Unescape String Tag  | 
                                                        |
| 204 | - case '___': //Unescape String Tag (with unescaped vars)  | 
                                                        |
| 205 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 206 | - $hTag->addContent($text);  | 
                                                        |
| 207 | - break;  | 
                                                        |
| 208 | - case '___': //Unescape String Tag  | 
                                                        |
| 209 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 210 | - $hTag->addContent($text);  | 
                                                        |
| 211 | - break;  | 
                                                        |
| 212 | - case '/': // HTML Comment  | 
                                                        |
| 213 | - case '//': // Non Printed Comment  | 
                                                        |
| 214 | - $hTag = new Tag\Comment($textcode);  | 
                                                        |
| 215 | - $hTag->addContent($text);  | 
                                                        |
| 216 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 217 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 218 | - }  | 
                                                        |
| 219 | - break;  | 
                                                        |
| 220 | - default:  | 
                                                        |
| 221 | - $attr = [];  | 
                                                        |
| 222 | -              if (isset($params[0]) && $params[0] == '[') { | 
                                                        |
| 223 | - $param = substr($params, 1, -1);  | 
                                                        |
| 224 | - $param = str_replace(['+', '\\&'], ['%2B', '%26'], $param);  | 
                                                        |
| 225 | - $attr = $this->parseQueryString($param);  | 
                                                        |
| 226 | - }  | 
                                                        |
| 227 | - $class = [];  | 
                                                        |
| 228 | - $id = '';  | 
                                                        |
| 229 | - $ref = '';  | 
                                                        |
| 230 | -              preg_match_all('/[#\.!][a-zA-Z0-9\-\_]+/m', $classid, $cid); | 
                                                        |
| 231 | -              if (isset($cid[0])) { | 
                                                        |
| 232 | -                foreach ($cid[0] as $s) { | 
                                                        |
| 233 | -                  if ($s[0] == '#') { | 
                                                        |
| 234 | - $id = substr($s, 1);  | 
                                                        |
| 235 | - }  | 
                                                        |
| 236 | -                  if ($s[0] == '.') { | 
                                                        |
| 237 | - $class[] = substr($s, 1);  | 
                                                        |
| 238 | - }  | 
                                                        |
| 239 | -                  if ($s[0] == '!') { | 
                                                        |
| 240 | - $ref = substr($s, 1);  | 
                                                        |
| 241 | - }  | 
                                                        |
| 242 | - }  | 
                                                        |
| 243 | - }  | 
                                                        |
| 244 | -              if ($ref) { | 
                                                        |
| 245 | - $hTag = new Tag\DynHtml($tag, $class, $attr, $id, $ref);  | 
                                                        |
| 246 | -              } else { | 
                                                        |
| 247 | - $hTag = new Tag\Html($tag, $class, $attr, $id);  | 
                                                        |
| 248 | - }  | 
                                                        |
| 249 | - $hTag->addContent($text);  | 
                                                        |
| 250 | - break;  | 
                                                        |
| 251 | - }  | 
                                                        |
| 252 | - $heir[$i] = $hTag;  | 
                                                        |
| 253 | -          if ($i > 0) { | 
                                                        |
| 254 | - $heir[$i - 1]->addChild($hTag);  | 
                                                        |
| 255 | -          } else { | 
                                                        |
| 256 | - $this->root[] = $hTag;  | 
                                                        |
| 257 | - }  | 
                                                        |
| 258 | -        } else { | 
                                                        |
| 259 | - throw new ParseError(  | 
                                                        |
| 260 | -            "Unable to parse line {$this->lineNo}\n\"$line\"/" . | 
                                                        |
| 261 | - preg_last_error(),  | 
                                                        |
| 262 | - );  | 
                                                        |
| 263 | - }  | 
                                                        |
| 264 | - }  | 
                                                        |
| 265 | - $this->lineNo++;  | 
                                                        |
| 266 | - }  | 
                                                        |
| 267 | - }  | 
                                                        |
| 268 | -  | 
                                                        |
| 269 | - function parseQueryString(string $qs):array  | 
                                                        |
| 270 | -  { | 
                                                        |
| 271 | - $out = [];  | 
                                                        |
| 272 | -    foreach (explode('&', $qs) as $s) { | 
                                                        |
| 273 | -      $kv = explode('=', $s, 2); | 
                                                        |
| 274 | - $out[urldecode($kv[0])] = isset($kv[1]) ? urldecode($kv[1]) : null;  | 
                                                        |
| 275 | - }  | 
                                                        |
| 276 | - return $out;  | 
                                                        |
| 277 | - }  | 
                                                        |
| 278 | -  | 
                                                        |
| 279 | - function output(bool $minify = false):string  | 
                                                        |
| 280 | -  { | 
                                                        |
| 281 | - $out = "<?php\nuse Seufert\\Hamle;\n?>";  | 
                                                        |
| 282 | -    foreach ($this->root as $tag) { | 
                                                        |
| 283 | - $out .= $tag->render(0, $minify);  | 
                                                        |
| 284 | - }  | 
                                                        |
| 285 | - return $out;  | 
                                                        |
| 286 | - }  | 
                                                        |
| 287 | -  | 
                                                        |
| 288 | - function consumeBlock(int $indent):array  | 
                                                        |
| 289 | -  { | 
                                                        |
| 290 | - $out = [];  | 
                                                        |
| 291 | - $m = [];  | 
                                                        |
| 292 | - while (  | 
                                                        |
| 293 | - $this->lineNo + 1 < $this->lineCount &&  | 
                                                        |
| 294 | - (!trim($this->lines[$this->lineNo + 1]) ||  | 
                                                        |
| 295 | - preg_match(  | 
                                                        |
| 296 | -          '/^(\s){' . $indent . '}((\s)+[^\s].*)$/', | 
                                                        |
| 297 | - $this->lines[$this->lineNo + 1],  | 
                                                        |
| 298 | - $m,  | 
                                                        |
| 299 | - ))  | 
                                                        |
| 300 | -    ) { | 
                                                        |
| 301 | -      if (trim($this->lines[$this->lineNo + 1])) { | 
                                                        |
| 302 | - $out[] = $m[2];  | 
                                                        |
| 303 | - }  | 
                                                        |
| 304 | - $this->lineNo++;  | 
                                                        |
| 305 | - }  | 
                                                        |
| 306 | - return $out;  | 
                                                        |
| 307 | - }  | 
                                                        |
| 308 | -  | 
                                                        |
| 309 | - function indentLevel(int $indent):int  | 
                                                        |
| 310 | -  { | 
                                                        |
| 311 | -    if (!count($this->indents)) { | 
                                                        |
| 312 | - $this->indents = [0 => $indent];  | 
                                                        |
| 313 | - // Key = indent level, Value = Depth in spaces  | 
                                                        |
| 314 | - return 0;  | 
                                                        |
| 315 | - }  | 
                                                        |
| 316 | -    foreach ($this->indents as $k => $v) { | 
                                                        |
| 317 | -      if ($v == $indent) { | 
                                                        |
| 318 | - $this->indents = array_slice($this->indents, 0, 1 + (int) $k );  | 
                                                        |
| 319 | - return $k;  | 
                                                        |
| 320 | - }  | 
                                                        |
| 321 | - }  | 
                                                        |
| 322 | - $this->indents[] = $indent;  | 
                                                        |
| 323 | - return max(array_keys($this->indents));  | 
                                                        |
| 324 | - }  | 
                                                        |
| 325 | -  | 
                                                        |
| 326 | - function getLineNo():int  | 
                                                        |
| 327 | -  { | 
                                                        |
| 328 | - return $this->lineNo;  | 
                                                        |
| 329 | - }  | 
                                                        |
| 330 | -}  | 
                                                        |
@@ -53,278 +53,3 @@  | 
                                                    ||
| 53 | 53 | */  | 
                                                        
| 54 | 54 | |
| 55 | 55 | const REGEX_PARSE_LINE = <<<'ENDREGEX'  | 
                                                        
| 56 | -  /^(\s*)(?:(?:([a-zA-Z0-9-]*)((?:[\.#!][\w\-\_]+)*)(\[(?:(?:\{\$[^\}]+\})?[^\\\]{]*?(?:\\.)*?(?:{[^\$])*?)+\])?)|([_\/]{1,3})|([\|:\$]\w+)|({?\$[^}]+}?)|)(?: (.*))?$/ | 
                                                        |
| 57 | - ENDREGEX;  | 
                                                        |
| 58 | -  | 
                                                        |
| 59 | - /**  | 
                                                        |
| 60 | - * @var int Current Line Number  | 
                                                        |
| 61 | - */  | 
                                                        |
| 62 | - protected int $lineNo = 0;  | 
                                                        |
| 63 | - /**  | 
                                                        |
| 64 | - * @var int Total Lines in File  | 
                                                        |
| 65 | - */  | 
                                                        |
| 66 | - protected int $lineCount = 0;  | 
                                                        |
| 67 | -  | 
                                                        |
| 68 | - function __construct()  | 
                                                        |
| 69 | -  { | 
                                                        |
| 70 | - $this->init();  | 
                                                        |
| 71 | - }  | 
                                                        |
| 72 | -  | 
                                                        |
| 73 | - /**  | 
                                                        |
| 74 | - * Clear Lines, and Line Number, so if output is  | 
                                                        |
| 75 | - * called, no output will be produced  | 
                                                        |
| 76 | - */  | 
                                                        |
| 77 | - protected function init():void  | 
                                                        |
| 78 | -  { | 
                                                        |
| 79 | - $this->lines = [];  | 
                                                        |
| 80 | - $this->lineNo = 0;  | 
                                                        |
| 81 | - $this->lineCount = 0;  | 
                                                        |
| 82 | - $this->root = [];  | 
                                                        |
| 83 | - }  | 
                                                        |
| 84 | -  | 
                                                        |
| 85 | - protected function loadLines(string $s):void  | 
                                                        |
| 86 | -  { | 
                                                        |
| 87 | -    $this->lines = explode("\n", str_replace("\r", '', $s)); | 
                                                        |
| 88 | - $this->lineCount = count($this->lines);  | 
                                                        |
| 89 | - $this->lineNo = 0;  | 
                                                        |
| 90 | - }  | 
                                                        |
| 91 | -  | 
                                                        |
| 92 | - function parseFilter(ParseFilter $filter):void  | 
                                                        |
| 93 | -  { | 
                                                        |
| 94 | -    foreach ($this->root as $k => $tag) { | 
                                                        |
| 95 | - $this->root[$k] = $filter->filterTag($tag);  | 
                                                        |
| 96 | - }  | 
                                                        |
| 97 | - }  | 
                                                        |
| 98 | -  | 
                                                        |
| 99 | - function parseSnip(string $s):void  | 
                                                        |
| 100 | -  { | 
                                                        |
| 101 | - //save root tags  | 
                                                        |
| 102 | - /** @var Tag[] $roots */  | 
                                                        |
| 103 | - $roots = $this->root;  | 
                                                        |
| 104 | - $this->root = [];  | 
                                                        |
| 105 | - $this->loadLines($s);  | 
                                                        |
| 106 | - $this->procLines();  | 
                                                        |
| 107 | - $this->root = array_merge($roots, $this->root);  | 
                                                        |
| 108 | - }  | 
                                                        |
| 109 | -  | 
                                                        |
| 110 | - function applySnip():void  | 
                                                        |
| 111 | -  { | 
                                                        |
| 112 | - /** @var Tag\Snippet[] $fwdSnip */  | 
                                                        |
| 113 | - $fwdSnip = [];  | 
                                                        |
| 114 | - /** @var Tag\Snippet[] $revSnip */  | 
                                                        |
| 115 | - $revSnip = [];  | 
                                                        |
| 116 | - /** @var Tag[] $roots */  | 
                                                        |
| 117 | - $roots = [];  | 
                                                        |
| 118 | -    foreach ($this->root as $snip) { | 
                                                        |
| 119 | -      if ($snip instanceof Tag\Snippet) { | 
                                                        |
| 120 | -        if ($snip->getType() == 'append') { | 
                                                        |
| 121 | - array_unshift($revSnip, $snip);  | 
                                                        |
| 122 | -        } else { | 
                                                        |
| 123 | - $fwdSnip[] = $snip;  | 
                                                        |
| 124 | - }  | 
                                                        |
| 125 | -      } else { | 
                                                        |
| 126 | - $roots[] = $snip;  | 
                                                        |
| 127 | - }  | 
                                                        |
| 128 | - }  | 
                                                        |
| 129 | -    foreach ($fwdSnip as $snip) { | 
                                                        |
| 130 | -      foreach ($roots as $root) { | 
                                                        |
| 131 | - $snip->apply($root);  | 
                                                        |
| 132 | - }  | 
                                                        |
| 133 | - }  | 
                                                        |
| 134 | -    foreach ($revSnip as $snip) { | 
                                                        |
| 135 | -      foreach ($roots as $root) { | 
                                                        |
| 136 | - $snip->apply($root);  | 
                                                        |
| 137 | - }  | 
                                                        |
| 138 | - }  | 
                                                        |
| 139 | - $this->root = $roots;  | 
                                                        |
| 140 | - }  | 
                                                        |
| 141 | -  | 
                                                        |
| 142 | - /**  | 
                                                        |
| 143 | - * Parse HAMLE template, from a string  | 
                                                        |
| 144 | - * @param string $s String to parse  | 
                                                        |
| 145 | - */  | 
                                                        |
| 146 | - function str($s):void  | 
                                                        |
| 147 | -  { | 
                                                        |
| 148 | - $this->init();  | 
                                                        |
| 149 | - $this->loadLines($s);  | 
                                                        |
| 150 | - $this->procLines();  | 
                                                        |
| 151 | - }  | 
                                                        |
| 152 | -  | 
                                                        |
| 153 | - function procLines():void  | 
                                                        |
| 154 | -  { | 
                                                        |
| 155 | - /* @var $heir Tag[] Tag Heirachy Array */  | 
                                                        |
| 156 | - $heir = [];  | 
                                                        |
| 157 | -    while ($this->lineNo < $this->lineCount) { | 
                                                        |
| 158 | - $line = $this->lines[$this->lineNo];  | 
                                                        |
| 159 | -      if (trim($line)) { | 
                                                        |
| 160 | -        if (preg_match(self::REGEX_PARSE_LINE, $line, $m)) { | 
                                                        |
| 161 | -          if (false !== strpos($m[1], "\t")) { | 
                                                        |
| 162 | - throw new ParseError(  | 
                                                        |
| 163 | - 'Tabs are not supported in templates at this time',  | 
                                                        |
| 164 | - );  | 
                                                        |
| 165 | - }  | 
                                                        |
| 166 | - $indent = strlen($m[1]);  | 
                                                        |
| 167 | - $tag = isset($m[2]) ? ($tag = $m[2]) : '';  | 
                                                        |
| 168 | - $classid = isset($m[3]) ? $m[3] : '';  | 
                                                        |
| 169 | - $params = str_replace(  | 
                                                        |
| 170 | - ['\[', '\]', '\\&'],  | 
                                                        |
| 171 | - ['[', ']', '%26'],  | 
                                                        |
| 172 | - isset($m[4]) ? $m[4] : '',  | 
                                                        |
| 173 | - );  | 
                                                        |
| 174 | - $textcode = isset($m[5]) ? $m[5] : '';  | 
                                                        |
| 175 | - $text = isset($m[8]) ? $m[8] : '';  | 
                                                        |
| 176 | - $code = isset($m[6]) ? $m[6] : '';  | 
                                                        |
| 177 | - $i = self::indentLevel($indent);  | 
                                                        |
| 178 | - unset($m[0]);  | 
                                                        |
| 179 | -          switch (strlen($code) ? $code[0] : ($textcode ? $textcode : '')) { | 
                                                        |
| 180 | - case '|': //Control Tag  | 
                                                        |
| 181 | -              if ($code == '|snippet') { | 
                                                        |
| 182 | - $hTag = new Tag\Snippet($text);  | 
                                                        |
| 183 | -              } elseif ($code == '|form') { | 
                                                        |
| 184 | - $hTag = new Tag\Form($text);  | 
                                                        |
| 185 | -              } elseif ($code == '|formhint') { | 
                                                        |
| 186 | - $hTag = new Tag\FormHint();  | 
                                                        |
| 187 | -              } elseif ($code == '|else') { | 
                                                        |
| 188 | - $hTag = new Tag\Control(substr($code, 1), $heir[$i - 1]);  | 
                                                        |
| 189 | - $hTag->setVar($text);  | 
                                                        |
| 190 | -              } else { | 
                                                        |
| 191 | - $hTag = new Tag\Control(substr($code, 1));  | 
                                                        |
| 192 | - $hTag->setVar($text);  | 
                                                        |
| 193 | - }  | 
                                                        |
| 194 | - break;  | 
                                                        |
| 195 | - case ':': //Filter Tag  | 
                                                        |
| 196 | - $hTag = new Tag\Filter(substr($code, 1));  | 
                                                        |
| 197 | - $hTag->addContent($text, Text::TOKEN_CODE);  | 
                                                        |
| 198 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 199 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 200 | - }  | 
                                                        |
| 201 | - break;  | 
                                                        |
| 202 | - case '_': //String Tag  | 
                                                        |
| 203 | - case '__': //Unescape String Tag  | 
                                                        |
| 204 | - case '___': //Unescape String Tag (with unescaped vars)  | 
                                                        |
| 205 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 206 | - $hTag->addContent($text);  | 
                                                        |
| 207 | - break;  | 
                                                        |
| 208 | - case '___': //Unescape String Tag  | 
                                                        |
| 209 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 210 | - $hTag->addContent($text);  | 
                                                        |
| 211 | - break;  | 
                                                        |
| 212 | - case '/': // HTML Comment  | 
                                                        |
| 213 | - case '//': // Non Printed Comment  | 
                                                        |
| 214 | - $hTag = new Tag\Comment($textcode);  | 
                                                        |
| 215 | - $hTag->addContent($text);  | 
                                                        |
| 216 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 217 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 218 | - }  | 
                                                        |
| 219 | - break;  | 
                                                        |
| 220 | - default:  | 
                                                        |
| 221 | - $attr = [];  | 
                                                        |
| 222 | -              if (isset($params[0]) && $params[0] == '[') { | 
                                                        |
| 223 | - $param = substr($params, 1, -1);  | 
                                                        |
| 224 | - $param = str_replace(['+', '\\&'], ['%2B', '%26'], $param);  | 
                                                        |
| 225 | - $attr = $this->parseQueryString($param);  | 
                                                        |
| 226 | - }  | 
                                                        |
| 227 | - $class = [];  | 
                                                        |
| 228 | - $id = '';  | 
                                                        |
| 229 | - $ref = '';  | 
                                                        |
| 230 | -              preg_match_all('/[#\.!][a-zA-Z0-9\-\_]+/m', $classid, $cid); | 
                                                        |
| 231 | -              if (isset($cid[0])) { | 
                                                        |
| 232 | -                foreach ($cid[0] as $s) { | 
                                                        |
| 233 | -                  if ($s[0] == '#') { | 
                                                        |
| 234 | - $id = substr($s, 1);  | 
                                                        |
| 235 | - }  | 
                                                        |
| 236 | -                  if ($s[0] == '.') { | 
                                                        |
| 237 | - $class[] = substr($s, 1);  | 
                                                        |
| 238 | - }  | 
                                                        |
| 239 | -                  if ($s[0] == '!') { | 
                                                        |
| 240 | - $ref = substr($s, 1);  | 
                                                        |
| 241 | - }  | 
                                                        |
| 242 | - }  | 
                                                        |
| 243 | - }  | 
                                                        |
| 244 | -              if ($ref) { | 
                                                        |
| 245 | - $hTag = new Tag\DynHtml($tag, $class, $attr, $id, $ref);  | 
                                                        |
| 246 | -              } else { | 
                                                        |
| 247 | - $hTag = new Tag\Html($tag, $class, $attr, $id);  | 
                                                        |
| 248 | - }  | 
                                                        |
| 249 | - $hTag->addContent($text);  | 
                                                        |
| 250 | - break;  | 
                                                        |
| 251 | - }  | 
                                                        |
| 252 | - $heir[$i] = $hTag;  | 
                                                        |
| 253 | -          if ($i > 0) { | 
                                                        |
| 254 | - $heir[$i - 1]->addChild($hTag);  | 
                                                        |
| 255 | -          } else { | 
                                                        |
| 256 | - $this->root[] = $hTag;  | 
                                                        |
| 257 | - }  | 
                                                        |
| 258 | -        } else { | 
                                                        |
| 259 | - throw new ParseError(  | 
                                                        |
| 260 | -            "Unable to parse line {$this->lineNo}\n\"$line\"/" . | 
                                                        |
| 261 | - preg_last_error(),  | 
                                                        |
| 262 | - );  | 
                                                        |
| 263 | - }  | 
                                                        |
| 264 | - }  | 
                                                        |
| 265 | - $this->lineNo++;  | 
                                                        |
| 266 | - }  | 
                                                        |
| 267 | - }  | 
                                                        |
| 268 | -  | 
                                                        |
| 269 | - function parseQueryString(string $qs):array  | 
                                                        |
| 270 | -  { | 
                                                        |
| 271 | - $out = [];  | 
                                                        |
| 272 | -    foreach (explode('&', $qs) as $s) { | 
                                                        |
| 273 | -      $kv = explode('=', $s, 2); | 
                                                        |
| 274 | - $out[urldecode($kv[0])] = isset($kv[1]) ? urldecode($kv[1]) : null;  | 
                                                        |
| 275 | - }  | 
                                                        |
| 276 | - return $out;  | 
                                                        |
| 277 | - }  | 
                                                        |
| 278 | -  | 
                                                        |
| 279 | - function output(bool $minify = false):string  | 
                                                        |
| 280 | -  { | 
                                                        |
| 281 | - $out = "<?php\nuse Seufert\\Hamle;\n?>";  | 
                                                        |
| 282 | -    foreach ($this->root as $tag) { | 
                                                        |
| 283 | - $out .= $tag->render(0, $minify);  | 
                                                        |
| 284 | - }  | 
                                                        |
| 285 | - return $out;  | 
                                                        |
| 286 | - }  | 
                                                        |
| 287 | -  | 
                                                        |
| 288 | - function consumeBlock(int $indent):array  | 
                                                        |
| 289 | -  { | 
                                                        |
| 290 | - $out = [];  | 
                                                        |
| 291 | - $m = [];  | 
                                                        |
| 292 | - while (  | 
                                                        |
| 293 | - $this->lineNo + 1 < $this->lineCount &&  | 
                                                        |
| 294 | - (!trim($this->lines[$this->lineNo + 1]) ||  | 
                                                        |
| 295 | - preg_match(  | 
                                                        |
| 296 | -          '/^(\s){' . $indent . '}((\s)+[^\s].*)$/', | 
                                                        |
| 297 | - $this->lines[$this->lineNo + 1],  | 
                                                        |
| 298 | - $m,  | 
                                                        |
| 299 | - ))  | 
                                                        |
| 300 | -    ) { | 
                                                        |
| 301 | -      if (trim($this->lines[$this->lineNo + 1])) { | 
                                                        |
| 302 | - $out[] = $m[2];  | 
                                                        |
| 303 | - }  | 
                                                        |
| 304 | - $this->lineNo++;  | 
                                                        |
| 305 | - }  | 
                                                        |
| 306 | - return $out;  | 
                                                        |
| 307 | - }  | 
                                                        |
| 308 | -  | 
                                                        |
| 309 | - function indentLevel(int $indent):int  | 
                                                        |
| 310 | -  { | 
                                                        |
| 311 | -    if (!count($this->indents)) { | 
                                                        |
| 312 | - $this->indents = [0 => $indent];  | 
                                                        |
| 313 | - // Key = indent level, Value = Depth in spaces  | 
                                                        |
| 314 | - return 0;  | 
                                                        |
| 315 | - }  | 
                                                        |
| 316 | -    foreach ($this->indents as $k => $v) { | 
                                                        |
| 317 | -      if ($v == $indent) { | 
                                                        |
| 318 | - $this->indents = array_slice($this->indents, 0, 1 + (int) $k );  | 
                                                        |
| 319 | - return $k;  | 
                                                        |
| 320 | - }  | 
                                                        |
| 321 | - }  | 
                                                        |
| 322 | - $this->indents[] = $indent;  | 
                                                        |
| 323 | - return max(array_keys($this->indents));  | 
                                                        |
| 324 | - }  | 
                                                        |
| 325 | -  | 
                                                        |
| 326 | - function getLineNo():int  | 
                                                        |
| 327 | -  { | 
                                                        |
| 328 | - return $this->lineNo;  | 
                                                        |
| 329 | - }  | 
                                                        |
| 330 | -}  | 
                                                        |
@@ -53,278 +53,3 @@  | 
                                                    ||
| 53 | 53 | */  | 
                                                        
| 54 | 54 | |
| 55 | 55 | const REGEX_PARSE_LINE = <<<'ENDREGEX'  | 
                                                        
| 56 | -  /^(\s*)(?:(?:([a-zA-Z0-9-]*)((?:[\.#!][\w\-\_]+)*)(\[(?:(?:\{\$[^\}]+\})?[^\\\]{]*?(?:\\.)*?(?:{[^\$])*?)+\])?)|([_\/]{1,3})|([\|:\$]\w+)|({?\$[^}]+}?)|)(?: (.*))?$/ | 
                                                        |
| 57 | - ENDREGEX;  | 
                                                        |
| 58 | -  | 
                                                        |
| 59 | - /**  | 
                                                        |
| 60 | - * @var int Current Line Number  | 
                                                        |
| 61 | - */  | 
                                                        |
| 62 | - protected int $lineNo = 0;  | 
                                                        |
| 63 | - /**  | 
                                                        |
| 64 | - * @var int Total Lines in File  | 
                                                        |
| 65 | - */  | 
                                                        |
| 66 | - protected int $lineCount = 0;  | 
                                                        |
| 67 | -  | 
                                                        |
| 68 | - function __construct()  | 
                                                        |
| 69 | -  { | 
                                                        |
| 70 | - $this->init();  | 
                                                        |
| 71 | - }  | 
                                                        |
| 72 | -  | 
                                                        |
| 73 | - /**  | 
                                                        |
| 74 | - * Clear Lines, and Line Number, so if output is  | 
                                                        |
| 75 | - * called, no output will be produced  | 
                                                        |
| 76 | - */  | 
                                                        |
| 77 | - protected function init():void  | 
                                                        |
| 78 | -  { | 
                                                        |
| 79 | - $this->lines = [];  | 
                                                        |
| 80 | - $this->lineNo = 0;  | 
                                                        |
| 81 | - $this->lineCount = 0;  | 
                                                        |
| 82 | - $this->root = [];  | 
                                                        |
| 83 | - }  | 
                                                        |
| 84 | -  | 
                                                        |
| 85 | - protected function loadLines(string $s):void  | 
                                                        |
| 86 | -  { | 
                                                        |
| 87 | -    $this->lines = explode("\n", str_replace("\r", '', $s)); | 
                                                        |
| 88 | - $this->lineCount = count($this->lines);  | 
                                                        |
| 89 | - $this->lineNo = 0;  | 
                                                        |
| 90 | - }  | 
                                                        |
| 91 | -  | 
                                                        |
| 92 | - function parseFilter(ParseFilter $filter):void  | 
                                                        |
| 93 | -  { | 
                                                        |
| 94 | -    foreach ($this->root as $k => $tag) { | 
                                                        |
| 95 | - $this->root[$k] = $filter->filterTag($tag);  | 
                                                        |
| 96 | - }  | 
                                                        |
| 97 | - }  | 
                                                        |
| 98 | -  | 
                                                        |
| 99 | - function parseSnip(string $s):void  | 
                                                        |
| 100 | -  { | 
                                                        |
| 101 | - //save root tags  | 
                                                        |
| 102 | - /** @var Tag[] $roots */  | 
                                                        |
| 103 | - $roots = $this->root;  | 
                                                        |
| 104 | - $this->root = [];  | 
                                                        |
| 105 | - $this->loadLines($s);  | 
                                                        |
| 106 | - $this->procLines();  | 
                                                        |
| 107 | - $this->root = array_merge($roots, $this->root);  | 
                                                        |
| 108 | - }  | 
                                                        |
| 109 | -  | 
                                                        |
| 110 | - function applySnip():void  | 
                                                        |
| 111 | -  { | 
                                                        |
| 112 | - /** @var Tag\Snippet[] $fwdSnip */  | 
                                                        |
| 113 | - $fwdSnip = [];  | 
                                                        |
| 114 | - /** @var Tag\Snippet[] $revSnip */  | 
                                                        |
| 115 | - $revSnip = [];  | 
                                                        |
| 116 | - /** @var Tag[] $roots */  | 
                                                        |
| 117 | - $roots = [];  | 
                                                        |
| 118 | -    foreach ($this->root as $snip) { | 
                                                        |
| 119 | -      if ($snip instanceof Tag\Snippet) { | 
                                                        |
| 120 | -        if ($snip->getType() == 'append') { | 
                                                        |
| 121 | - array_unshift($revSnip, $snip);  | 
                                                        |
| 122 | -        } else { | 
                                                        |
| 123 | - $fwdSnip[] = $snip;  | 
                                                        |
| 124 | - }  | 
                                                        |
| 125 | -      } else { | 
                                                        |
| 126 | - $roots[] = $snip;  | 
                                                        |
| 127 | - }  | 
                                                        |
| 128 | - }  | 
                                                        |
| 129 | -    foreach ($fwdSnip as $snip) { | 
                                                        |
| 130 | -      foreach ($roots as $root) { | 
                                                        |
| 131 | - $snip->apply($root);  | 
                                                        |
| 132 | - }  | 
                                                        |
| 133 | - }  | 
                                                        |
| 134 | -    foreach ($revSnip as $snip) { | 
                                                        |
| 135 | -      foreach ($roots as $root) { | 
                                                        |
| 136 | - $snip->apply($root);  | 
                                                        |
| 137 | - }  | 
                                                        |
| 138 | - }  | 
                                                        |
| 139 | - $this->root = $roots;  | 
                                                        |
| 140 | - }  | 
                                                        |
| 141 | -  | 
                                                        |
| 142 | - /**  | 
                                                        |
| 143 | - * Parse HAMLE template, from a string  | 
                                                        |
| 144 | - * @param string $s String to parse  | 
                                                        |
| 145 | - */  | 
                                                        |
| 146 | - function str($s):void  | 
                                                        |
| 147 | -  { | 
                                                        |
| 148 | - $this->init();  | 
                                                        |
| 149 | - $this->loadLines($s);  | 
                                                        |
| 150 | - $this->procLines();  | 
                                                        |
| 151 | - }  | 
                                                        |
| 152 | -  | 
                                                        |
| 153 | - function procLines():void  | 
                                                        |
| 154 | -  { | 
                                                        |
| 155 | - /* @var $heir Tag[] Tag Heirachy Array */  | 
                                                        |
| 156 | - $heir = [];  | 
                                                        |
| 157 | -    while ($this->lineNo < $this->lineCount) { | 
                                                        |
| 158 | - $line = $this->lines[$this->lineNo];  | 
                                                        |
| 159 | -      if (trim($line)) { | 
                                                        |
| 160 | -        if (preg_match(self::REGEX_PARSE_LINE, $line, $m)) { | 
                                                        |
| 161 | -          if (false !== strpos($m[1], "\t")) { | 
                                                        |
| 162 | - throw new ParseError(  | 
                                                        |
| 163 | - 'Tabs are not supported in templates at this time',  | 
                                                        |
| 164 | - );  | 
                                                        |
| 165 | - }  | 
                                                        |
| 166 | - $indent = strlen($m[1]);  | 
                                                        |
| 167 | - $tag = isset($m[2]) ? ($tag = $m[2]) : '';  | 
                                                        |
| 168 | - $classid = isset($m[3]) ? $m[3] : '';  | 
                                                        |
| 169 | - $params = str_replace(  | 
                                                        |
| 170 | - ['\[', '\]', '\\&'],  | 
                                                        |
| 171 | - ['[', ']', '%26'],  | 
                                                        |
| 172 | - isset($m[4]) ? $m[4] : '',  | 
                                                        |
| 173 | - );  | 
                                                        |
| 174 | - $textcode = isset($m[5]) ? $m[5] : '';  | 
                                                        |
| 175 | - $text = isset($m[8]) ? $m[8] : '';  | 
                                                        |
| 176 | - $code = isset($m[6]) ? $m[6] : '';  | 
                                                        |
| 177 | - $i = self::indentLevel($indent);  | 
                                                        |
| 178 | - unset($m[0]);  | 
                                                        |
| 179 | -          switch (strlen($code) ? $code[0] : ($textcode ? $textcode : '')) { | 
                                                        |
| 180 | - case '|': //Control Tag  | 
                                                        |
| 181 | -              if ($code == '|snippet') { | 
                                                        |
| 182 | - $hTag = new Tag\Snippet($text);  | 
                                                        |
| 183 | -              } elseif ($code == '|form') { | 
                                                        |
| 184 | - $hTag = new Tag\Form($text);  | 
                                                        |
| 185 | -              } elseif ($code == '|formhint') { | 
                                                        |
| 186 | - $hTag = new Tag\FormHint();  | 
                                                        |
| 187 | -              } elseif ($code == '|else') { | 
                                                        |
| 188 | - $hTag = new Tag\Control(substr($code, 1), $heir[$i - 1]);  | 
                                                        |
| 189 | - $hTag->setVar($text);  | 
                                                        |
| 190 | -              } else { | 
                                                        |
| 191 | - $hTag = new Tag\Control(substr($code, 1));  | 
                                                        |
| 192 | - $hTag->setVar($text);  | 
                                                        |
| 193 | - }  | 
                                                        |
| 194 | - break;  | 
                                                        |
| 195 | - case ':': //Filter Tag  | 
                                                        |
| 196 | - $hTag = new Tag\Filter(substr($code, 1));  | 
                                                        |
| 197 | - $hTag->addContent($text, Text::TOKEN_CODE);  | 
                                                        |
| 198 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 199 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 200 | - }  | 
                                                        |
| 201 | - break;  | 
                                                        |
| 202 | - case '_': //String Tag  | 
                                                        |
| 203 | - case '__': //Unescape String Tag  | 
                                                        |
| 204 | - case '___': //Unescape String Tag (with unescaped vars)  | 
                                                        |
| 205 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 206 | - $hTag->addContent($text);  | 
                                                        |
| 207 | - break;  | 
                                                        |
| 208 | - case '___': //Unescape String Tag  | 
                                                        |
| 209 | - $hTag = new Tag\Text($textcode);  | 
                                                        |
| 210 | - $hTag->addContent($text);  | 
                                                        |
| 211 | - break;  | 
                                                        |
| 212 | - case '/': // HTML Comment  | 
                                                        |
| 213 | - case '//': // Non Printed Comment  | 
                                                        |
| 214 | - $hTag = new Tag\Comment($textcode);  | 
                                                        |
| 215 | - $hTag->addContent($text);  | 
                                                        |
| 216 | -              foreach ($this->consumeBlock($indent) as $l) { | 
                                                        |
| 217 | - $hTag->addContent($l, Text::TOKEN_CODE);  | 
                                                        |
| 218 | - }  | 
                                                        |
| 219 | - break;  | 
                                                        |
| 220 | - default:  | 
                                                        |
| 221 | - $attr = [];  | 
                                                        |
| 222 | -              if (isset($params[0]) && $params[0] == '[') { | 
                                                        |
| 223 | - $param = substr($params, 1, -1);  | 
                                                        |
| 224 | - $param = str_replace(['+', '\\&'], ['%2B', '%26'], $param);  | 
                                                        |
| 225 | - $attr = $this->parseQueryString($param);  | 
                                                        |
| 226 | - }  | 
                                                        |
| 227 | - $class = [];  | 
                                                        |
| 228 | - $id = '';  | 
                                                        |
| 229 | - $ref = '';  | 
                                                        |
| 230 | -              preg_match_all('/[#\.!][a-zA-Z0-9\-\_]+/m', $classid, $cid); | 
                                                        |
| 231 | -              if (isset($cid[0])) { | 
                                                        |
| 232 | -                foreach ($cid[0] as $s) { | 
                                                        |
| 233 | -                  if ($s[0] == '#') { | 
                                                        |
| 234 | - $id = substr($s, 1);  | 
                                                        |
| 235 | - }  | 
                                                        |
| 236 | -                  if ($s[0] == '.') { | 
                                                        |
| 237 | - $class[] = substr($s, 1);  | 
                                                        |
| 238 | - }  | 
                                                        |
| 239 | -                  if ($s[0] == '!') { | 
                                                        |
| 240 | - $ref = substr($s, 1);  | 
                                                        |
| 241 | - }  | 
                                                        |
| 242 | - }  | 
                                                        |
| 243 | - }  | 
                                                        |
| 244 | -              if ($ref) { | 
                                                        |
| 245 | - $hTag = new Tag\DynHtml($tag, $class, $attr, $id, $ref);  | 
                                                        |
| 246 | -              } else { | 
                                                        |
| 247 | - $hTag = new Tag\Html($tag, $class, $attr, $id);  | 
                                                        |
| 248 | - }  | 
                                                        |
| 249 | - $hTag->addContent($text);  | 
                                                        |
| 250 | - break;  | 
                                                        |
| 251 | - }  | 
                                                        |
| 252 | - $heir[$i] = $hTag;  | 
                                                        |
| 253 | -          if ($i > 0) { | 
                                                        |
| 254 | - $heir[$i - 1]->addChild($hTag);  | 
                                                        |
| 255 | -          } else { | 
                                                        |
| 256 | - $this->root[] = $hTag;  | 
                                                        |
| 257 | - }  | 
                                                        |
| 258 | -        } else { | 
                                                        |
| 259 | - throw new ParseError(  | 
                                                        |
| 260 | -            "Unable to parse line {$this->lineNo}\n\"$line\"/" . | 
                                                        |
| 261 | - preg_last_error(),  | 
                                                        |
| 262 | - );  | 
                                                        |
| 263 | - }  | 
                                                        |
| 264 | - }  | 
                                                        |
| 265 | - $this->lineNo++;  | 
                                                        |
| 266 | - }  | 
                                                        |
| 267 | - }  | 
                                                        |
| 268 | -  | 
                                                        |
| 269 | - function parseQueryString(string $qs):array  | 
                                                        |
| 270 | -  { | 
                                                        |
| 271 | - $out = [];  | 
                                                        |
| 272 | -    foreach (explode('&', $qs) as $s) { | 
                                                        |
| 273 | -      $kv = explode('=', $s, 2); | 
                                                        |
| 274 | - $out[urldecode($kv[0])] = isset($kv[1]) ? urldecode($kv[1]) : null;  | 
                                                        |
| 275 | - }  | 
                                                        |
| 276 | - return $out;  | 
                                                        |
| 277 | - }  | 
                                                        |
| 278 | -  | 
                                                        |
| 279 | - function output(bool $minify = false):string  | 
                                                        |
| 280 | -  { | 
                                                        |
| 281 | - $out = "<?php\nuse Seufert\\Hamle;\n?>";  | 
                                                        |
| 282 | -    foreach ($this->root as $tag) { | 
                                                        |
| 283 | - $out .= $tag->render(0, $minify);  | 
                                                        |
| 284 | - }  | 
                                                        |
| 285 | - return $out;  | 
                                                        |
| 286 | - }  | 
                                                        |
| 287 | -  | 
                                                        |
| 288 | - function consumeBlock(int $indent):array  | 
                                                        |
| 289 | -  { | 
                                                        |
| 290 | - $out = [];  | 
                                                        |
| 291 | - $m = [];  | 
                                                        |
| 292 | - while (  | 
                                                        |
| 293 | - $this->lineNo + 1 < $this->lineCount &&  | 
                                                        |
| 294 | - (!trim($this->lines[$this->lineNo + 1]) ||  | 
                                                        |
| 295 | - preg_match(  | 
                                                        |
| 296 | -          '/^(\s){' . $indent . '}((\s)+[^\s].*)$/', | 
                                                        |
| 297 | - $this->lines[$this->lineNo + 1],  | 
                                                        |
| 298 | - $m,  | 
                                                        |
| 299 | - ))  | 
                                                        |
| 300 | -    ) { | 
                                                        |
| 301 | -      if (trim($this->lines[$this->lineNo + 1])) { | 
                                                        |
| 302 | - $out[] = $m[2];  | 
                                                        |
| 303 | - }  | 
                                                        |
| 304 | - $this->lineNo++;  | 
                                                        |
| 305 | - }  | 
                                                        |
| 306 | - return $out;  | 
                                                        |
| 307 | - }  | 
                                                        |
| 308 | -  | 
                                                        |
| 309 | - function indentLevel(int $indent):int  | 
                                                        |
| 310 | -  { | 
                                                        |
| 311 | -    if (!count($this->indents)) { | 
                                                        |
| 312 | - $this->indents = [0 => $indent];  | 
                                                        |
| 313 | - // Key = indent level, Value = Depth in spaces  | 
                                                        |
| 314 | - return 0;  | 
                                                        |
| 315 | - }  | 
                                                        |
| 316 | -    foreach ($this->indents as $k => $v) { | 
                                                        |
| 317 | -      if ($v == $indent) { | 
                                                        |
| 318 | - $this->indents = array_slice($this->indents, 0, 1 + (int) $k );  | 
                                                        |
| 319 | - return $k;  | 
                                                        |
| 320 | - }  | 
                                                        |
| 321 | - }  | 
                                                        |
| 322 | - $this->indents[] = $indent;  | 
                                                        |
| 323 | - return max(array_keys($this->indents));  | 
                                                        |
| 324 | - }  | 
                                                        |
| 325 | -  | 
                                                        |
| 326 | - function getLineNo():int  | 
                                                        |
| 327 | -  { | 
                                                        |
| 328 | - return $this->lineNo;  | 
                                                        |
| 329 | - }  | 
                                                        |
| 330 | -}  | 
                                                        |
@@ -70,7 +70,7 @@ discard block  | 
                                                    ||
| 70 | 70 | ]);  | 
                                                        
| 71 | 71 |      } catch (SyntaxError $e) { | 
                                                        
| 72 | 72 | throw new ParseError(  | 
                                                        
| 73 | - 'Unable to parse:' . $s . "\n\n" . $e->getMessage(),  | 
                                                        |
| 73 | + 'Unable to parse:'.$s."\n\n".$e->getMessage(),  | 
                                                        |
| 74 | 74 | 0,  | 
                                                        
| 75 | 75 | $e,  | 
                                                        
| 76 | 76 | );  | 
                                                        
@@ -141,7 +141,7 @@ discard block  | 
                                                    ||
| 141 | 141 | self::varToCode($limit),  | 
                                                        
| 142 | 142 | self::varToCode($offset),  | 
                                                        
| 143 | 143 | ];  | 
                                                        
| 144 | -    return 'Hamle\Run::modelTypeId(' . join(',', $opt) . ')'; | 
                                                        |
| 144 | +    return 'Hamle\Run::modelTypeId('.join(',', $opt).')'; | 
                                                        |
| 145 | 145 | }  | 
                                                        
| 146 | 146 | |
| 147 | 147 | function toHTML(bool $escape = false): string  | 
                                                        
@@ -156,16 +156,16 @@ discard block  | 
                                                    ||
| 156 | 156 | }  | 
                                                        
| 157 | 157 | break;  | 
                                                        
| 158 | 158 | case 'scopeName':  | 
                                                        
| 159 | - $out .= '<?=' . self::renderScopeName($node) . '?>';  | 
                                                        |
| 159 | + $out .= '<?='.self::renderScopeName($node).'?>';  | 
                                                        |
| 160 | 160 | break;  | 
                                                        
| 161 | 161 | case 'scopeThis':  | 
                                                        
| 162 | - $out .= '<?=' . self::renderScopeThis($node) . '?>';  | 
                                                        |
| 162 | + $out .= '<?='.self::renderScopeThis($node).'?>';  | 
                                                        |
| 163 | 163 | break;  | 
                                                        
| 164 | 164 | case 'expr':  | 
                                                        
| 165 | - $out .= '<?=' . self::renderExpr($node) . '?>';  | 
                                                        |
| 165 | + $out .= '<?='.self::renderExpr($node).'?>';  | 
                                                        |
| 166 | 166 | break;  | 
                                                        
| 167 | 167 | default:  | 
                                                        
| 168 | -          throw new \RuntimeException('Invalid Node:' . $node['type']); | 
                                                        |
| 168 | +          throw new \RuntimeException('Invalid Node:'.$node['type']); | 
                                                        |
| 169 | 169 | }  | 
                                                        
| 170 | 170 | }  | 
                                                        
| 171 | 171 | return $out;  | 
                                                        
@@ -194,7 +194,7 @@ discard block  | 
                                                    ||
| 194 | 194 | $out[] = self::renderExpr($node);  | 
                                                        
| 195 | 195 | break;  | 
                                                        
| 196 | 196 | default:  | 
                                                        
| 197 | -          throw new \RuntimeException('Invalid Node:' . $node['type']); | 
                                                        |
| 197 | +          throw new \RuntimeException('Invalid Node:'.$node['type']); | 
                                                        |
| 198 | 198 | }  | 
                                                        
| 199 | 199 | }  | 
                                                        
| 200 | 200 |      return join('.', $out); | 
                                                        
@@ -202,7 +202,7 @@ discard block  | 
                                                    ||
| 202 | 202 | |
| 203 | 203 | function doEval(): mixed  | 
                                                        
| 204 | 204 |    { | 
                                                        
| 205 | -    return eval('use Seufert\Hamle; return ' . $this->toPHP() . ';'); | 
                                                        |
| 205 | +    return eval('use Seufert\Hamle; return '.$this->toPHP().';'); | 
                                                        |
| 206 | 206 | }  | 
                                                        
| 207 | 207 | |
| 208 | 208 | static function varToCode(mixed $var): mixed  | 
                                                        
@@ -210,9 +210,9 @@ discard block  | 
                                                    ||
| 210 | 210 |      if (is_array($var)) { | 
                                                        
| 211 | 211 | $code = [];  | 
                                                        
| 212 | 212 |        foreach ($var as $key => $value) { | 
                                                        
| 213 | - $code[] = self::varToCode($key) . '=>' . self::varToCode($value);  | 
                                                        |
| 213 | + $code[] = self::varToCode($key).'=>'.self::varToCode($value);  | 
                                                        |
| 214 | 214 | }  | 
                                                        
| 215 | -      return 'array(' . implode(',', $code) . ')'; //remove unnecessary coma | 
                                                        |
| 215 | +      return 'array('.implode(',', $code).')'; //remove unnecessary coma | 
                                                        |
| 216 | 216 | }  | 
                                                        
| 217 | 217 |      if (is_bool($var)) { | 
                                                        
| 218 | 218 | return $var ? 'TRUE' : 'FALSE';  | 
                                                        
@@ -224,16 +224,16 @@ discard block  | 
                                                    ||
| 224 | 224 | return $var->toPHP();  | 
                                                        
| 225 | 225 | }  | 
                                                        
| 226 | 226 |      if (strpos($var, "\n") !== false) { | 
                                                        
| 227 | - return '"' .  | 
                                                        |
| 227 | + return '"'.  | 
                                                        |
| 228 | 228 | str_replace(  | 
                                                        
| 229 | 229 | ['\\', '$', '"', "\n"],  | 
                                                        
| 230 | 230 | ['\\\\', '\$', '\\"', '\\n'],  | 
                                                        
| 231 | 231 | $var,  | 
                                                        
| 232 | - ) .  | 
                                                        |
| 232 | + ).  | 
                                                        |
| 233 | 233 | '"';  | 
                                                        
| 234 | 234 | }  | 
                                                        
| 235 | - return "'" .  | 
                                                        |
| 236 | - str_replace(['\\', '$', "'"], ['\\\\', '$', "\\'"], $var) .  | 
                                                        |
| 235 | + return "'".  | 
                                                        |
| 236 | + str_replace(['\\', '$', "'"], ['\\\\', '$', "\\'"], $var).  | 
                                                        |
| 237 | 237 | "'";  | 
                                                        
| 238 | 238 | }  | 
                                                        
| 239 | 239 | |
@@ -92,8 +92,8 @@ discard block  | 
                                                    ||
| 92 | 92 | }  | 
                                                        
| 93 | 93 |      if (!$baseModel instanceof Model) { | 
                                                        
| 94 | 94 | throw new Exception\Unsupported(  | 
                                                        
| 95 | -        'Unsupported Model(' . | 
                                                        |
| 96 | - get_class($baseModel) .  | 
                                                        |
| 95 | +        'Unsupported Model('. | 
                                                        |
| 96 | + get_class($baseModel).  | 
                                                        |
| 97 | 97 | ') Type was passed, it must implement hamleModel',  | 
                                                        
| 98 | 98 | );  | 
                                                        
| 99 | 99 | }  | 
                                                        
@@ -128,7 +128,7 @@ discard block  | 
                                                    ||
| 128 | 128 |        throw new Exception\NotFound("Unable to find HAMLE Template ($template)"); | 
                                                        
| 129 | 129 | }  | 
                                                        
| 130 | 130 | $this->cacheFile = $this->setup->cachePath(  | 
                                                        
| 131 | -      str_replace('/', '-', $hamleFile) . '.php', | 
                                                        |
| 131 | +      str_replace('/', '-', $hamleFile).'.php', | 
                                                        |
| 132 | 132 | );  | 
                                                        
| 133 | 133 |      $this->setup->debugLog("Set cache file path to ({$this->cacheFile})"); | 
                                                        
| 134 | 134 | $cacheFileAge = is_file($this->cacheFile) ? filemtime($this->cacheFile) : 0;  | 
                                                        
@@ -193,7 +193,7 @@ discard block  | 
                                                    ||
| 193 | 193 | function string(string $hamleString): void  | 
                                                        
| 194 | 194 |    { | 
                                                        
| 195 | 195 | $md5 = md5($hamleString);  | 
                                                        
| 196 | - $stringId = substr($md5, 0, 12) . substr($md5, 24, 8);  | 
                                                        |
| 196 | + $stringId = substr($md5, 0, 12).substr($md5, 24, 8);  | 
                                                        |
| 197 | 197 |      $this->cacheFile = $this->setup->cachePath("string.$stringId.hamle.php"); | 
                                                        
| 198 | 198 |      if (!is_file($this->cacheFile)) { | 
                                                        
| 199 | 199 | $this->parse($hamleString);  | 
                                                        
@@ -32,7 +32,7 @@  | 
                                                    ||
| 32 | 32 | static function fromParser(  | 
                                                        
| 33 | 33 | array $chars,  | 
                                                        
| 34 | 34 | ?Evaluated $expr = null,  | 
                                                        
| 35 | - string|StringLit|StringConcat $rhs = null  | 
                                                        |
| 35 | + string | StringLit | StringConcat $rhs = null  | 
                                                        |
| 36 | 36 |    ): self { | 
                                                        
| 37 | 37 | $o = [];  | 
                                                        
| 38 | 38 |      if ($chars) { | 
                                                        
@@ -19,7 +19,7 @@ discard block  | 
                                                    ||
| 19 | 19 | $this->filters = $filters;  | 
                                                        
| 20 | 20 | }  | 
                                                        
| 21 | 21 | |
| 22 | - static function for(string $rel, array $filters): self  | 
                                                        |
| 22 | + static function for (string $rel, array $filters): self  | 
                                                        |
| 23 | 23 |    { | 
                                                        
| 24 | 24 | return new self(  | 
                                                        
| 25 | 25 | $rel === '>' ? Hamle::REL_CHILD : Hamle::REL_PARENT,  | 
                                                        
@@ -30,9 +30,9 @@ discard block  | 
                                                    ||
| 30 | 30 | public function apply(string $out): string  | 
                                                        
| 31 | 31 |    { | 
                                                        
| 32 | 32 | $out =  | 
                                                        
| 33 | - $out .  | 
                                                        |
| 34 | -      "->hamleRel({$this->rel}," . | 
                                                        |
| 35 | - Query::queryParams($this->filters, true) .  | 
                                                        |
| 33 | + $out.  | 
                                                        |
| 34 | +      "->hamleRel({$this->rel},". | 
                                                        |
| 35 | + Query::queryParams($this->filters, true).  | 
                                                        |
| 36 | 36 | ')';  | 
                                                        
| 37 | 37 |      if ($this->chain) { | 
                                                        
| 38 | 38 | $out = $this->chain->apply($out);  | 
                                                        
@@ -50,9 +50,9 @@  | 
                                                    ||
| 50 | 50 | function toPHP(): string  | 
                                                        
| 51 | 51 |    { | 
                                                        
| 52 | 52 |      if (is_numeric($this->scope)) { | 
                                                        
| 53 | -      return 'Hamle\\Scope::get(' . Text::varToCode($this->scope) . ')'; | 
                                                        |
| 53 | +      return 'Hamle\\Scope::get('.Text::varToCode($this->scope).')'; | 
                                                        |
| 54 | 54 |      } else { | 
                                                        
| 55 | -      return 'Hamle\\Scope::getName(' . Text::varToCode($this->scope) . ')'; | 
                                                        |
| 55 | +      return 'Hamle\\Scope::getName('.Text::varToCode($this->scope).')'; | 
                                                        |
| 56 | 56 | }  | 
                                                        
| 57 | 57 | }  | 
                                                        
| 58 | 58 | |