dirty_exit_recovery = array( 'DSTRING' => '/[^">]*+("|$|(?=[>]))/', 'SSTRING' => "/[^'>]*+('|$|(?=[>]))/", 'COMMENT1' => '/(?> [^\\-]+ | -(?!->))*(?:-->|$)/x', 'COMMENT2' => '/[^>]*+(?:>|$)/s', 'CDATA' => '/(?>[^\\]]+|\\](?!\\]>))*(?:\\]{2}>|$)/xs', 'ESC' => '/[^;]*+(?:;|$)/', 'TYPE' => '/[^\s]*/', 'VALUE' => '/[^\s]*/', 'HTMLTAG' => '/[^\s]*/', ); $this->rule_tag_map = array( 'DSTRING' => 'STRING', 'SSTRING' => 'STRING', 'COMMENT1' => 'COMMENT', 'COMMENT2' => 'COMMENT', 'CDATA' => 'COMMENT', ); parent::__construct($src); } function scan_child($lang) { assert (isset($this->child_scanners[$lang])); $scanner = $this->child_scanners[$lang]; $scanner->pos($this->pos()); $substr = $scanner->main(); $this->tokens[] = array(null, $scanner->tagged(), true); $this->pos($scanner->pos()); if ($scanner->interrupt) { $this->child_state = array($lang, $this->pos()); } else { $this->child_state = null; } } function init() { $this->add_pattern('', '/&/'); if ($this->embedded_server) { $this->add_pattern('TERM', $this->server_tags); } $this->add_pattern('', '/state_ = 'global'; if ($this->scripts) { $js = new LuminousJavaScriptScanner($this->string()); $js->embedded_server = $this->embedded_server; $js->embedded_html = true; $js->server_tags = $this->server_tags; $js->init(); $css = new LuminousCSSScanner($this->string()); $css->embedded_server = $this->embedded_server; $css->embedded_html = true; $css->server_tags = $this->server_tags; $css->init(); $this->add_child_scanner('js', $js); $this->add_child_scanner('css', $css); } } private $tagname = ''; private $expecting = ''; function main() { $this->start(); $this->interrupt = false; while (!$this->eos()) { $index = $this->pos(); if ($this->embedded_server && $this->check($this->server_tags)) { $this->interrupt = true; break; } if (!$this->clean_exit) { try { $tok = $this->resume(); if ($this->server_break($tok)) break; $this->record($this->match(), $tok); } catch (Exception $e) { if (LUMINOUS_DEBUG) throw $e; else $this->clean_exit = true; } continue; } if ($this->child_state !== null && $this->child_state[1] < $this->pos()) { $this->scan_child($this->child_state[0]); continue; } $in_tag = $this->state_ === 'tag'; if (!$in_tag) { $next = $this->next_match(false); if($next) { $skip = $next[1] - $this->pos(); $this->record($this->get($skip), null); if ($next[0] === 'TERM') { $this->interrupt = true; break; } } } else { $this->skip_whitespace(); if ($this->embedded_server && $this->check($this->server_tags)) { $this->interrupt = true; break; } } $index = $this->pos(); $c = $this->peek(); $tok = null; $get = false; if (!$in_tag && $c === '&' && $this->scan('/&[^;\s]+;/') ) $tok = 'ESC'; elseif(!$in_tag && $c === '<') { if ($this->peek(2) === 'scan('/(<)(!DOCTYPE)/i')) { // special case: doctype $matches = $this->match_groups(); $this->record($matches[1], null); $this->record($matches[2], 'KEYWORD'); $this->state_ = 'tag'; continue; } // urgh elseif($this->scan('/ [^\\]]+ | \\](?!\\]>) )* (?: \\]\\]> | $ ) /ixs' )) $tok = 'CDATA'; elseif($this->scan('/|$)/xs')) $tok = 'COMMENT1'; elseif($this->scan('/]*+(?:>|$)/s')) $tok = 'COMMENT2'; else assert(0); } else { // check for