diff options
| author | Lester Caine <lester@lsces.co.uk> | 2026-05-14 19:52:12 +0100 |
|---|---|---|
| committer | Lester Caine <lester@lsces.co.uk> | 2026-05-14 19:52:12 +0100 |
| commit | f42e735f78f46ce7ea63acb301f57df9eeae4ef9 (patch) | |
| tree | 451fcb013a8ad2ccf471d534b38d51f266b6021d /includes | |
| parent | c105a9834fd9c5a320d41422c50fa84e5bc12084 (diff) | |
| download | wiki-f42e735f78f46ce7ea63acb301f57df9eeae4ef9.tar.gz wiki-f42e735f78f46ce7ea63acb301f57df9eeae4ef9.tar.bz2 wiki-f42e735f78f46ce7ea63acb301f57df9eeae4ef9.zip | |
Move legacy libraries into the relevant package for easier maintenance
Diffstat (limited to 'includes')
| -rwxr-xr-x | includes/htmlparser/html_parser_inc.php | 492 | ||||
| -rwxr-xr-x | includes/htmlparser/htmlgrammar.cmp | 1 | ||||
| -rwxr-xr-x | includes/htmlparser/htmlgrammar.dat | 1176 | ||||
| -rwxr-xr-x | includes/htmlparser/htmlgrammarparser.inc | 478 | ||||
| -rwxr-xr-x | includes/htmlparser/readme.eng.txt | 19 | ||||
| -rwxr-xr-x | includes/htmlparser/rebuildgrammar.php | 13 | ||||
| -rwxr-xr-x | includes/tar.class.php | 467 | ||||
| -rwxr-xr-x | includes/zip_lib.php | 805 |
8 files changed, 3451 insertions, 0 deletions
diff --git a/includes/htmlparser/html_parser_inc.php b/includes/htmlparser/html_parser_inc.php new file mode 100755 index 0000000..5965711 --- /dev/null +++ b/includes/htmlparser/html_parser_inc.php @@ -0,0 +1,492 @@ +<?php +if (!defined("_ECHOSERVER_HTML_PARSER")) { +define("_ECHOSERVER_HTML_PARSER",1); + +class HtmlParser { + var $pos, + $tagpos, + $length, + $data, + $stacktag, + $stacktagpos, + $name, + $quotstate, + $quottype, + $parname, + $pars, + $tagname, + $content, + $contentpos, + $allreadyparsed, + $pg, + $dc, + $nc, + $qc, + $prevstate, + $processtag, + $processpar, + $processparvalue, + $c, + $cp, + $text, + $incomment, + $skipto, + $tagreg, + $wasquot; +/********************************************************************************** + * Class constructor + **********************************************************************************/ + function HtmlParser($data,$grammar,$name="",$datatype=0) { + $this->dc=[" ","\t","\r","\n","<",">",'"',"'","=","/"]; + $this->nc=["<",">","=","/"]; + $this->qc=['"',"'"]; + $this->sc=["\r","\n"," ","\t"]; + $this->prevstate=["state"=>0,"word"=>""]; + $this->pg=&$grammar; + $this->pos=0; + $this->stacktag=[]; + $this->stacktagpos=-1; + $this->content=[]; + $this->content["contentpos"]=-1; + $this->c=&$this->content; + $this->cp=-1; + $this->quotstate=-1; + $this->allreadyparsed=0; + $this->text=""; + $this->processtag=0; + $this->processpar=0; + $this->processparvalue=0; + $this->slevel=[0]; + $this->slevelpos=0; + $this->quottype=""; + $this->skipto=""; + $this->incomment=0; + $this->tagreg=[]; + $this->wasquot=0; + + if(isset($this->data) && is_array($this->data)) { + $this->content=&$data; + $this->allreadyparsed=1; + return; + } + clearstatcache(); + $this->name=$data; + if (!$datatype) { + $this->name=$name; + $this->data=$data; + $this->length=strlen($this->data); + return; + } + if (!$fp=fopen($this->name,"rb")) { + $this->SetError(1,"Can't open file $this->name.",0,0,"Error"); + return; + } + flock($fp,1); + $this->data=fread($fp,filesize($this->name)); + flock($fp,3); + fclose($fp); + $this->length=strlen($this->data); + } + +/******************************************************************************************** + * Get word from data + ********************************************************************************************/ + function GetWord(&$word) { + $word=""; + $this->wasquot=0; + if ($this->pos>$this->length) return false; + while (1) { + if ($this->pos>$this->length) return false; + if ($this->pos==$this->length) { + $this->pos++; + return true; + } + if ($this->data[$this->pos]=="<") { + if ($this->data[$this->pos+1]=="!") + if ($this->length>6 && $this->length-$this->pos+1>6) { + if (substr($this->data,$this->pos,4)=="<!--") { + $this->incomment=1; + while($this->pos<$this->length-3) { + if (substr($this->data,$this->pos,3)=="-->") { + $word.="-->"; + $this->pos+=3; + break; + } + $word.=$this->data[$this->pos++]; + } + if ($this->incomment) break; + } + } + } + if (!$this->processtag) { + if ($this->data[$this->pos]=="<") { + $this->processtag=1; + $this->tagpos=strlen($this->text); + } else { + $this->text.=$this->data[$this->pos++]; + continue; + } + } + if (in_array($this->data[$this->pos],$this->dc)) { + if (($this->data[$this->pos]=="<" || $this->data[$this->pos]==">") && $this->quotstate==-1 && $this->processparvalue) { + $this->processparvalue=0; + return true; + } + if (in_array($this->data[$this->pos],$this->sc) && $this->quotstate==-1) { + $this->text.=$this->data[$this->pos++]; + if (strlen($word)) { + if ($this->processparvalue) $this->processparvalue=0; + return true; + } + continue; + } + if (!strlen($word)) { + if (in_array($this->data[$this->pos],$this->qc) && $this->processpar) { + if ($this->quotstate==-1) { + $this->wasquot=1; + $this->quotstate*=-1; + $this->quottype=$this->data[$this->pos]; + $this->text.=$this->data[$this->pos++]; + continue; + } elseif ($this->quottype==$this->data[$this->pos]) { + $this->quotstate*=-1; + $this->quottype=$this->data[$this->pos]; + $this->processpar=$this->processparvalue=0; + $this->text.=$this->data[$this->pos++]; + return true; + } + } elseif (in_array($this->data[$this->pos],$this->nc)) { + $word.=$this->data[$this->pos]; + $this->text.=$this->data[$this->pos++]; + if ($this->processparvalue) + continue; + + return true; + } + } else { + if (in_array($this->data[$this->pos],$this->qc) && $this->processpar) { + if ($this->quotstate==1) { + if ($this->data[$this->pos]==$this->quottype && $this->processparvalue) { + $this->quotstate*=-1; + $this->quottype=$this->data[$this->pos]; + $this->processpar=$this->processparvalue=0; + $this->text.=$this->data[$this->pos++]; +// continue; + } else { + if ($this->data[$this->pos]==$this->quottype) { + $this->quotstate*=-1; + $this->quottype=""; + } + $word.=$this->data[$this->pos]; + $this->text.=$this->data[$this->pos++]; + continue; + } + } + return true; + } + if (in_array($this->data[$this->pos],$this->nc)) { + if ($this->quotstate==-1) { + if ($this->processparvalue) { + if($this->data[$this->pos]!="/" && $this->data[$this->pos]!="=") return true; + $word.=$this->data[$this->pos]; + $this->text.=$this->data[$this->pos++]; + continue; + } + } else { + $word.=$this->data[$this->pos]; + $this->text.=$this->data[$this->pos++]; + continue; + } + return true; + } elseif ($this->quotstate==-1 && $this->processparvalue && strlen($word)) { + if ($this->data[$this->pos]==" ") { + $this->text.=$this->data[$this->pos++]; + $this->processparvalue=0; + return true; + } + } + + } + } + $word.=$this->data[$this->pos]; + $this->text.=$this->data[$this->pos++]; + } + return true; + } + +/******************************************************************************************** + * Parse HTML code + ******************************************************************************************** +<tagname [parname=|parnane=["|']parvalue["|']|parname][/]> | +<[/]tagname> + +in/state 0 1 2 3 4 5 6 7 8 +< 1 -1 -1 -1 -1 -1 -1 -1 -1 +/ -1 7 6 6 6 6 -1 -1 -1 += -1 -1 -1 4 -1 -1 -1 -1 -1 +> -1 -1 -2 -2 -2 -2 -2 -1 -3 +anyword -1 2 3 3 5 3 -1 8 -1 + +-3 end parse close tag +-2 end parse open tag +-1 error + 0 begin parse + 1 got '<', waiting '/' or any word as tag name + 2 got any word as tagname, waiting '/' or '>' or any word as parameter name + 3 got any word as parameter name, waiting '/' or '>' or '=' or any word as parameter name + 4 got '=' waiting '/' or '>' or any word as parameter value + 5 got any word as parameter value, waiting '/' or '>' or any word as parameter name + 6 got '/' waiting '>' + 7 got '/', waiting any word as close tagname + 8 got any word as close tag name, waiting '>' + ********************************************************************************************/ + function Parse() { + $automat=[ +// states 0 1 2 3 4 5 6 7 8 + "0"=>[ 1, -1, -1, -1, -1, -1, -1, -1, -1],// < + "1"=>[-1, 7, 6, 6, 6, 6, -1, -1, -1],// / + "2"=>[-1, -1, -1, 4, -1, -1, -1, -1, -1],// = + "3"=>[-1, -1, -2, -2, -2, -2, -2, -1, -3],// > + "4"=>[-1, 2, 3, 3, 5, 3, -1, 8, -1], // any word + ]; + if (!strlen($this->data)) return; + $instates=["<"=>0,"/"=>1,"="=>2,">"=>3]; + $parcount=0; + $state=0; + $this->c=&$this->content; + $this->cp=&$this->content["contentpos"]; + $this->stacktag[0]["tag"]=&$this->c; + $this->stacktag[0]["level"]=&$this->slevel; + $this->stacktag[0]["levelpos"]=0; + $this->stacktagpos=0; + while(1) { + if (!$isword=$this->GetWord($word)) break; + $w=strtolower($word); + if (!isset($instates[$w])) + $instate=4; + else + $instate=$instates[$w]; +//print htmlspecialchars($word).",$state,$instate,$this->quottype<br>"; + $state=$automat[$instate][$state]; + if ($this->wasquot && $state==6) $state=5; +//print htmlspecialchars($word).",$state<br>"; + switch($state) { + case -3:// end parse close tag + if (strlen($this->skipto) && $this->tagname!=$this->skipto) { + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->pars=[]; + break; + } + $this->skipto=""; + $script=($this->tagname=="script") ? 1:0; + $this->AddNewText(substr($this->text,0,$this->tagpos),$script); + $this->AddNewTag(0); + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->quottype=""; + $this->quotstate=-1; + $this->text=""; + $this->pars=[]; + $this->tagpos=0; + break; + case -2:// end parse open tag + if (strlen($this->skipto)) { + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->pars=[]; + break; + } + $this->AddNewText(substr($this->text,0,$this->tagpos)); + $this->AddNewTag(1,$xmlclose); + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->quottype=""; + $this->quotstate=-1; + $this->text=""; + $this->pars=[]; + $this->tagpos=0; + if (isset($this->pg[$this->tagname]["nohavetags"]) && !strlen($this->skipto)) $this->skipto=$this->tagname; + break; + case -1:// Error found + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->pars=[]; + if ($this->incomment) { + if (strlen($this->text)) { + $this->AddNewText($this->text); + $this->text=""; + $this->tagpos=0; + } + $this->AddNewText($word,0,1); + $this->incomment=0; + break; + } + if ($word=="<") { + $state=1; + $this->processtag=1; + $this->processparvalue=0; + $this->tagpos=strlen($this->text)-1; + $this->quottype=""; + $this->quotstate=-1; + } + break; + case 2:// got any word as tagname, waiting '/' or '>' or any word as parameter name + $this->tagname=$w; + $xmlclose=0; + if (!ereg("^[a-zA-Z0-9!_-]+$",$this->tagname) || strlen($this->skipto)) { + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->quottype=""; + $this->quotstate=-1; + $this->pars=[]; + break; + } + break; + case 3:// got any word as parameter name, waiting '/' or '>' or '=' or any word as parameter name + $this->parname=$w; + if (!ereg("^[a-zA-Z0-9!_-]+$",$this->parname) || strlen($this->skipto)) { + $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0; + $this->quottype=""; + $this->quotstate=-1; + $this->pars=[]; + break; + } + $this->processpar=1; + if ($w!="/") { + $parcount++; + $this->pars[$this->parname]["single"]=1; + } else + $xmlclose=1; + break; + case 4:// got '=' waiting '/' or '>' or any word as parameter value + $this->processparvalue=1; + break; + case 5:// got any word as parameter value, waiting '/' or '>' or any word as parameter name + if ($this->parname!="/") { + unset($this->pars[$this->parname]["single"]); + $this->pars[$this->parname]["value"]=$word; + $this->pars[$this->parname]["quot"]=$this->quottype; + } + $this->quottype=""; + $this->processpar=$this->processparvalue=0; + break; + case 6:// got '/' waiting '>' + $xmlclose=1; + break; + case 8:// got any word as close tag name, waiting '>' + $this->tagname=$w; + break; + } + $this->prevstate["states"]=$state; + $this->prevstate["word"]=$word; + } + if (strlen($this->text)) $this->AddNewText($this->text); + } +/******************************************************************************************** + * Add new tag + ********************************************************************************************/ + function AddNewTag($open,$xmlclose=0) { + $actionclose=0; + if (!$open && in_array( $this->tagname, $this->pg ) && $this->pg[$this->tagname]["endtag"]!="absent") $actionclose=1; + + if ($open) + for ($i=$this->stacktagpos;$i>0;$i--) { + $ct=&$this->stacktag[$i]["tag"]; + $t=&$ct[$ct["contentpos"]]; + $tagname=$t["data"]["name"]; + if (isset($this->pg[$tagname]["closeon"])) { + if (isset($this->pg[$tagname]["closeon"]["in"]) && sizeof($this->pg[$tagname]["closeon"]["in"]) && in_array($this->tagname,$this->pg[$tagname]["closeon"]["in"]) + || isset($this->pg[$tagname]["closeon"]["notin"]) && sizeof($this->pg[$tagname]["closeon"]["notin"]) && !in_array($this->tagname,$this->pg[$tagname]["closeon"]["notin"])) { + $actionclose=2; + break; + } + } + if ($actionclose!=2) $i=-1; + } + + if ($actionclose) { + if ($actionclose==1) { + $i=$this->FindTag($this->tagname); + if ($i>-1) + if ($this->tagreg[$this->tagname]!=$this->stacktag[$i]["num"]) + $i=-1; + } + if ($i>-1) { + $this->c=&$this->stacktag[$i]["tag"]; + $this->cp=&$this->c["contentpos"]; + $this->stacktagpos=$i; + if ($actionclose==1) { + $c=&$this->c[$this->c["contentpos"]]["content"]; + $cp=&$this->c[$this->c["contentpos"]]["content"]["contentpos"]; + $cp++; + $c[$cp]["type"]="tag"; + $c[$cp]["data"]["name"]=$this->tagname; + $c[$cp]["data"]["type"]="close"; + if (isset($this->tagreg[$this->tagname])) + if ($this->tagreg[$this->tagname]) + $this->tagreg[$this->tagname]--; + $this->stacktag[$this->stacktagpos]["num"]=$this->tagreg[$this->tagname]; + $this->stacktagpos--; + } + if ($this->stacktagpos<sizeof($this->stacktag)) + for ($i=$this->stacktagpos+1;$i<sizeof($this->stacktag);$i++) + unset($this->stacktag[$i]); + if ($actionclose==1) return; + } + } + $this->cp++; + $this->c[$this->cp]["type"]="tag"; + $this->c[$this->cp]["data"]["name"]=$this->tagname; + $this->c[$this->cp]["data"]["type"]=($open) ? "open" : "close"; + if (!$open) + if (isset($this->tagreg[$this->tagname])) + if ($this->tagreg[$this->tagname]) + $this->tagreg[$this->tagname]--; + if ($xmlclose) $this->c[$this->cp]["xmlclose"]=1; + if (sizeof($this->pars)) $this->c[$this->cp]["pars"]=$this->pars; + if ($open && !$xmlclose && in_array( $this->tagname, $this->pg ) && $this->pg[$this->tagname]["endtag"]!="absent") { + if (!isset($this->tagreg[$this->tagname])) $this->tagreg[$this->tagname]=0; + $this->tagreg[$this->tagname]++; + $this->stacktagpos++; + $this->stacktag[$this->stacktagpos]["tag"]=&$this->c; + $this->stacktag[$this->stacktagpos]["num"]=$this->tagreg[$this->tagname]; + $this->c[$this->cp]["content"]=[]; + $this->c[$this->cp]["content"]["contentpos"]=-1; + $this->c=&$this->c[$this->cp]["content"]; + $this->cp=&$this->c["contentpos"]; + } + } + +/******************************************************************************************** + * Add new text + ********************************************************************************************/ + function AddNewText($text,$script=0,$comment=0) { + if (!strlen($text)) return; + $this->cp++; + if (!$comment) + $this->c[$this->cp]["type"]="text"; + else + $this->c[$this->cp]["type"]="comment"; + if ($script) { + $inputarray=["/_top/","/top.location.href/","/([ \n]+)?window\.name/","/parent.location/"]; + $replarray=["_echoserver_file_space","parent.frames('_echoserver_file_space').src","//window.name","parent.frames('_echoserver_file_space').src"]; +/* + $text=str_replace("_top","_echoserver_file_space",$text); + $text=str_replace("top.location.href","parent.frames('_echoserver_file_space').src",$text); + $text=preg_replace("/([ \n]+)?window\.name/","//window.name",$text); +*/ + $text=preg_replace($inputarray,$replarray,$text); + + } + $this->c[$this->cp]["data"]=$text; + $this->text=""; + } + +/******************************************************************************************** + * Find first tag in stack + ********************************************************************************************/ + function FindTag($tagname) { + for($i=$this->stacktagpos;$i>=0;$i--) + if ($this->stacktag[$i]["tag"][$this->stacktag[$i]["tag"]["contentpos"]]["data"]["name"]==$tagname) + return $i; + return -1; + } +} + +} //_ECHOSERVER_HTML_PARSER +?> diff --git a/includes/htmlparser/htmlgrammar.cmp b/includes/htmlparser/htmlgrammar.cmp new file mode 100755 index 0000000..f4fcf0e --- /dev/null +++ b/includes/htmlparser/htmlgrammar.cmp @@ -0,0 +1 @@ +a:57:{s:3:"pre";a:4:{s:3:"tag";s:3:"pre";s:6:"endtag";s:7:"present";s:10:"nohavetags";s:0:"";s:4:"pars";a:0:{}}s:2:"hr";a:3:{s:3:"tag";s:2:"hr";s:6:"endtag";s:6:"absent";s:4:"pars";a:3:{s:5:"color";a:1:{s:3:"par";s:5:"color";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:7:"noshade";a:3:{s:3:"par";s:7:"noshade";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}}}s:8:"noframes";a:3:{s:3:"tag";s:8:"noframes";s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:8:"frameset";a:4:{s:3:"tag";s:8:"frameset";s:6:"endtag";s:9:"canabsent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:8:{s:4:"rows";a:1:{s:3:"par";s:4:"rows";}s:4:"cols";a:1:{s:3:"par";s:4:"cols";}s:11:"frameborder";a:1:{s:3:"par";s:11:"frameborder";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:12:"framespacing";a:1:{s:3:"par";s:12:"framespacing";}s:12:"marginheight";a:1:{s:3:"par";s:12:"marginheight";}s:11:"marginwidth";a:1:{s:3:"par";s:11:"marginwidth";}s:8:"noresize";a:1:{s:3:"par";s:8:"noresize";}}}s:5:"frame";a:4:{s:3:"tag";s:5:"frame";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:19:"tags/tag_frame2.gif";s:4:"pars";a:10:{s:4:"name";a:1:{s:3:"par";s:4:"name";}s:6:"target";a:1:{s:3:"par";s:6:"target";}s:9:"scrolling";a:1:{s:3:"par";s:9:"scrolling";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:11:"frameborder";a:1:{s:3:"par";s:11:"frameborder";}s:12:"framespacing";a:1:{s:3:"par";s:12:"framespacing";}s:12:"marginheight";a:1:{s:3:"par";s:12:"marginheight";}s:11:"marginwidth";a:1:{s:3:"par";s:11:"marginwidth";}s:8:"noresize";a:1:{s:3:"par";s:8:"noresize";}s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}}}s:6:"iframe";a:3:{s:3:"tag";s:6:"iframe";s:14:"pictureforedit";s:20:"tags/tag_iframe2.gif";s:4:"pars";a:0:{}}s:4:"html";a:6:{s:3:"tag";s:4:"html";s:6:"endtag";s:7:"present";s:13:"edittagsafter";s:4:"body";s:7:"comment";s:4:"Html";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:0:{}}s:4:"meta";a:4:{s:3:"tag";s:4:"meta";s:6:"endtag";s:6:"absent";s:13:"edittagsafter";s:4:"body";s:4:"pars";a:0:{}}s:6:"script";a:6:{s:3:"tag";s:6:"script";s:10:"nohavetags";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:19:"tags/tag_script.gif";s:14:"edittagsbefore";s:6:"script";s:4:"pars";a:2:{s:8:"language";a:1:{s:3:"par";s:8:"language";}s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}}}s:4:"nobr";a:4:{s:3:"tag";s:4:"nobr";s:7:"closeon";a:2:{s:5:"notin";a:14:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:6:"center";i:3;s:4:"font";i:4;s:1:"i";i:5;s:1:"b";i:6;s:1:"u";i:7;s:2:"tt";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:6:"script";}s:2:"in";a:0:{}}s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:1:"p";a:5:{s:3:"tag";s:1:"p";s:7:"closeon";a:2:{s:5:"notin";a:23:{i:0;s:1:"a";i:1;s:3:"map";i:2;s:4:"area";i:3;s:6:"strong";i:4;s:3:"sup";i:5;s:4:"font";i:6;s:1:"i";i:7;s:1:"b";i:8;s:1:"u";i:9;s:2:"tt";i:10;s:3:"img";i:11;s:1:"s";i:12;s:3:"big";i:13;s:5:"small";i:14;s:6:"strike";i:15;s:4:"nobr";i:16;s:2:"br";i:17;s:6:"script";i:18;s:5:"input";i:19;s:6:"select";i:20;s:8:"textarea";i:21;s:6:"option";i:22;s:6:"button";}s:2:"in";a:0:{}}s:6:"endtag";s:9:"canabsent";s:14:"pictureforedit";s:15:"tags/tag_p2.gif";s:4:"pars";a:1:{s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:24:"_Translator_edit_p_align";}}}s:2:"th";a:3:{s:3:"tag";s:2:"th";s:6:"endtag";s:6:"absent";s:4:"pars";a:1:{s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:25:"_Translator_edit_th_align";}}}s:8:"noscript";a:3:{s:3:"tag";s:8:"noscript";s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:5:"style";a:4:{s:3:"tag";s:5:"style";s:10:"nohavetags";s:0:"";s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:4:"head";a:4:{s:3:"tag";s:4:"head";s:6:"endtag";s:7:"present";s:13:"edittagsafter";s:4:"body";s:4:"pars";a:0:{}}s:6:"center";a:5:{s:3:"tag";s:6:"center";s:6:"endtag";s:7:"present";s:7:"comment";s:6:"Center";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:0:{}}s:3:"img";a:5:{s:3:"tag";s:3:"img";s:6:"endtag";s:6:"absent";s:7:"comment";s:7:"Picture";s:14:"pictureforedit";s:16:"tags/tag_img.gif";s:4:"pars";a:16:{s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:3:"alt";a:1:{s:3:"par";s:3:"alt";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:26:"_Translator_edit_img_align";}s:6:"vspace";a:1:{s:3:"par";s:6:"vspace";}s:6:"hspace";a:1:{s:3:"par";s:6:"hspace";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:6:"usemap";a:2:{s:3:"par";s:6:"usemap";s:10:"editmethod";s:32:"_Translator_edit_standart_usemap";}}}s:1:"a";a:8:{s:3:"tag";s:1:"a";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"edittagsbefore";s:1:"a";s:7:"comment";s:3:"Url";s:14:"pictureforedit";s:14:"tags/tag_a.gif";s:7:"closeon";a:2:{s:5:"notin";a:19:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:6:"center";i:3;s:4:"font";i:4;s:1:"i";i:5;s:1:"b";i:6;s:1:"u";i:7;s:2:"tt";i:8;s:3:"img";i:9;s:1:"s";i:10;s:3:"big";i:11;s:5:"small";i:12;s:6:"strike";i:13;s:4:"nobr";i:14;s:2:"br";i:15;s:6:"script";i:16;s:2:"li";i:17;s:2:"ol";i:18;s:2:"ul";}s:2:"in";a:1:{i:0;s:1:"a";}}s:4:"pars";a:24:{s:4:"href";a:3:{s:3:"par";s:4:"href";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:8:"hreflang";a:1:{s:3:"par";s:8:"hreflang";}s:3:"rel";a:1:{s:3:"par";s:3:"rel";}s:3:"rev";a:1:{s:3:"par";s:3:"rev";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:5:"shape";a:1:{s:3:"par";s:5:"shape";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:8:"tabindex";a:1:{s:3:"par";s:8:"tabindex";}s:6:"target";a:1:{s:3:"par";s:6:"target";}}}s:2:"ul";a:6:{s:3:"tag";s:2:"ul";s:6:"endtag";s:7:"present";s:7:"comment";s:15:"Unsequence list";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"closeon";a:2:{s:5:"notin";a:17:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";i:15;s:2:"li";i:16;s:2:"ol";}s:2:"in";a:3:{i:0;s:5:"table";i:1;s:2:"tr";i:2;s:2:"td";}}s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:4:"type";a:1:{s:3:"par";s:4:"type";}}}s:2:"li";a:7:{s:3:"tag";s:2:"li";s:6:"endtag";s:7:"present";s:7:"comment";s:12:"List element";s:14:"pictureforedit";s:12:"tags/tag.gif";s:13:"nohavesametag";s:0:"";s:7:"closeon";a:2:{s:5:"notin";a:17:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";i:15;s:2:"ol";i:16;s:2:"ul";}s:2:"in";a:1:{i:0;s:2:"li";}}s:4:"pars";a:18:{s:5:"value";a:1:{s:3:"par";s:5:"value";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:4:"type";a:1:{s:3:"par";s:4:"type";}}}s:2:"ol";a:7:{s:3:"tag";s:2:"ol";s:6:"endtag";s:7:"present";s:7:"comment";s:13:"Sequence list";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"closeon";a:2:{s:5:"notin";a:17:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";i:15;s:2:"ol";i:16;s:2:"ul";}s:2:"in";a:1:{i:0;s:2:"ol";}}s:13:"nohavesametag";s:0:"";s:4:"pars";a:18:{s:5:"start";a:1:{s:3:"par";s:5:"start";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:4:"type";a:1:{s:3:"par";s:4:"type";}}}s:5:"title";a:5:{s:3:"tag";s:5:"title";s:6:"endtag";s:7:"present";s:7:"comment";s:11:"Page header";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:0:{}}s:8:"textarea";a:6:{s:3:"tag";s:8:"textarea";s:10:"nohavetags";s:0:"";s:6:"endtag";s:7:"present";s:7:"comment";s:8:"Textarea";s:14:"pictureforedit";s:21:"tags/tag_textarea.gif";s:4:"pars";a:26:{s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:4:"rows";a:1:{s:3:"par";s:4:"rows";}s:4:"cols";a:1:{s:3:"par";s:4:"cols";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:4:"wrap";a:1:{s:3:"par";s:4:"wrap";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:8:"onselect";a:1:{s:3:"par";s:8:"onselect";}s:8:"onchange";a:1:{s:3:"par";s:8:"onchange";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"tr";a:6:{s:3:"tag";s:2:"tr";s:6:"endtag";s:7:"present";s:7:"comment";s:9:"Table row";s:14:"pictureforedit";s:15:"tags/tag_tr.gif";s:13:"edittagsafter";s:2:"td";s:4:"pars";a:20:{s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:25:"_Translator_edit_td_align";}s:6:"valign";a:2:{s:3:"par";s:6:"valign";s:10:"editmethod";s:26:"_Translator_edit_td_valign";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:10:"background";a:1:{s:3:"par";s:10:"background";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"td";a:6:{s:3:"tag";s:2:"td";s:6:"endtag";s:7:"present";s:7:"comment";s:10:"Table cell";s:14:"pictureforedit";s:15:"tags/tag_td.gif";s:13:"edittagsafter";s:2:"td";s:4:"pars";a:25:{s:7:"colspan";a:1:{s:3:"par";s:7:"colspan";}s:7:"rowspan";a:1:{s:3:"par";s:7:"rowspan";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:10:"background";a:1:{s:3:"par";s:10:"background";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:25:"_Translator_edit_td_align";}s:6:"valign";a:2:{s:3:"par";s:6:"valign";s:10:"editmethod";s:26:"_Translator_edit_td_valign";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:6:"nowrap";a:3:{s:3:"par";s:6:"nowrap";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}}}s:5:"table";a:5:{s:3:"tag";s:5:"table";s:6:"endtag";s:7:"present";s:7:"comment";s:5:"Table";s:14:"pictureforedit";s:18:"tags/tag_table.gif";s:4:"pars";a:26:{s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:10:"background";a:1:{s:3:"par";s:10:"background";}s:11:"cellspacing";a:1:{s:3:"par";s:11:"cellspacing";}s:11:"cellpadding";a:1:{s:3:"par";s:11:"cellpadding";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:11:"bordercolor";a:1:{s:3:"par";s:11:"bordercolor";}s:7:"summary";a:1:{s:3:"par";s:7:"summary";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:28:"_Translator_edit_table_align";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:4:"area";a:5:{s:3:"tag";s:4:"area";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:10:"Map region";s:4:"pars";a:22:{s:4:"href";a:3:{s:3:"par";s:4:"href";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:5:"shape";a:2:{s:3:"par";s:5:"shape";s:10:"editmethod";s:31:"_Translator_edit_standart_shape";}s:6:"coords";a:1:{s:3:"par";s:6:"coords";}s:6:"usemap";a:1:{s:3:"par";s:6:"usemap";}s:3:"alt";a:1:{s:3:"par";s:3:"alt";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:8:"tabindex";a:1:{s:3:"par";s:8:"tabindex";}}}s:4:"span";a:5:{s:3:"tag";s:4:"span";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:4:"span";s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"b";a:7:{s:3:"tag";s:1:"b";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:15:"tags/tag_b2.gif";s:7:"comment";s:1:"B";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"b";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"tt";a:7:{s:3:"tag";s:2:"tt";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"TT";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:2:"tt";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"i";a:7:{s:3:"tag";s:1:"i";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:15:"tags/tag_i2.gif";s:7:"comment";s:1:"I";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"i";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:3:"big";a:7:{s:3:"tag";s:3:"big";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:3:"Big";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:3:"big";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:5:"small";a:7:{s:3:"tag";s:5:"small";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:5:"Small";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:5:"small";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:6:"strike";a:7:{s:3:"tag";s:6:"strike";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:6:"Strike";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:6:"strike";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"s";a:7:{s:3:"tag";s:1:"s";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:1:"S";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"s";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"u";a:7:{s:3:"tag";s:1:"u";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:15:"tags/tag_u2.gif";s:7:"comment";s:1:"U";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"u";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:3:"map";a:7:{s:3:"tag";s:3:"map";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:3:"Map";s:7:"closeon";a:2:{s:5:"notin";a:1:{i:0;s:4:"area";}s:2:"in";a:1:{i:0;s:3:"map";}}s:4:"pars";a:1:{s:4:"name";a:1:{s:3:"par";s:4:"name";}}}s:2:"br";a:4:{s:3:"tag";s:2:"br";s:4:"edit";s:1:"0";s:6:"endtag";s:6:"absent";s:4:"pars";a:5:{s:5:"clear";a:1:{s:3:"par";s:5:"clear";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"style";a:1:{s:3:"par";s:5:"style";}}}s:4:"base";a:5:{s:3:"tag";s:4:"base";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:4:"Base";s:4:"pars";a:2:{s:4:"href";a:3:{s:3:"par";s:4:"href";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:6:"target";a:1:{s:3:"par";s:6:"target";}}}s:8:"basefont";a:5:{s:3:"tag";s:8:"basefont";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:8:"Basefont";s:4:"pars";a:7:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:5:"color";a:1:{s:3:"par";s:5:"color";}s:4:"face";a:1:{s:3:"par";s:4:"face";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}}}s:4:"body";a:8:{s:3:"tag";s:4:"body";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:17:"tags/tag_body.gif";s:13:"edittagsafter";s:4:"body";s:7:"comment";s:9:"Page body";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:4:"body";}}s:4:"pars";a:27:{s:10:"background";a:1:{s:3:"par";s:10:"background";}s:4:"text";a:1:{s:3:"par";s:4:"text";}s:4:"link";a:1:{s:3:"par";s:4:"link";}s:5:"vlink";a:1:{s:3:"par";s:5:"vlink";}s:5:"alink";a:1:{s:3:"par";s:5:"alink";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:9:"topmargin";a:1:{s:3:"par";s:9:"topmargin";}s:10:"leftmargin";a:1:{s:3:"par";s:10:"leftmargin";}s:11:"marginwidth";a:1:{s:3:"par";s:11:"marginwidth";}s:12:"marginheight";a:1:{s:3:"par";s:12:"marginheight";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:6:"onload";a:1:{s:3:"par";s:6:"onload";}s:8:"onunload";a:1:{s:3:"par";s:8:"onunload";}}}s:6:"button";a:7:{s:3:"tag";s:6:"button";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:19:"tags/tag_button.gif";s:7:"comment";s:6:"Button";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"center";i:1;s:4:"font";i:2;s:1:"i";i:3;s:1:"b";i:4;s:1:"u";i:5;s:2:"tt";i:6;s:1:"a";i:7;s:3:"img";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:6:"button";}}s:4:"pars";a:18:{s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"value";a:1:{s:3:"par";s:5:"value";}s:4:"type";a:1:{s:3:"par";s:4:"type";}s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:6:"usemap";a:1:{s:3:"par";s:6:"usemap";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}}}s:3:"div";a:5:{s:3:"tag";s:3:"div";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:16:"tags/tag_div.gif";s:7:"comment";s:8:"Division";s:4:"pars";a:15:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:26:"_Translator_edit_div_align";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:4:"font";a:6:{s:3:"tag";s:4:"font";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:18:"tags/tag_font2.gif";s:7:"comment";s:4:"Font";s:7:"closeon";a:2:{s:5:"notin";a:13:{i:0;s:1:"i";i:1;s:1:"b";i:2;s:1:"u";i:3;s:2:"tt";i:4;s:1:"a";i:5;s:3:"img";i:6;s:1:"s";i:7;s:3:"big";i:8;s:5:"small";i:9;s:6:"strike";i:10;s:4:"nobr";i:11;s:2:"br";i:12;s:6:"script";}s:2:"in";a:0:{}}s:4:"pars";a:9:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:5:"color";a:1:{s:3:"par";s:5:"color";}s:4:"face";a:1:{s:3:"par";s:4:"face";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}}}s:4:"form";a:5:{s:3:"tag";s:4:"form";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:17:"tags/tag_form.gif";s:7:"comment";s:4:"Form";s:4:"pars";a:23:{s:6:"action";a:3:{s:3:"par";s:6:"action";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:6:"method";a:1:{s:3:"par";s:6:"method";}s:7:"enctype";a:1:{s:3:"par";s:7:"enctype";}s:14:"accept-charset";a:1:{s:3:"par";s:14:"accept-charset";}s:6:"accept";a:1:{s:3:"par";s:6:"accept";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:6:"target";a:1:{s:3:"par";s:6:"target";}s:8:"onsubmit";a:1:{s:3:"par";s:8:"onsubmit";}s:7:"onreset";a:1:{s:3:"par";s:7:"onreset";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h1";a:7:{s:3:"tag";s:2:"h1";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"hl";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h1";}}s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h2";a:7:{s:3:"tag";s:2:"h2";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h2";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h2";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h3";a:7:{s:3:"tag";s:2:"h3";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h3";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h3";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h4";a:7:{s:3:"tag";s:2:"h4";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h4";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h4";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h5";a:7:{s:3:"tag";s:2:"h5";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h5";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h5";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h6";a:7:{s:3:"tag";s:2:"h6";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h6";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h6";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:5:"input";a:5:{s:3:"tag";s:5:"input";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:18:"tags/tag_input.gif";s:7:"comment";s:18:"Form input element";s:4:"pars";a:38:{s:4:"type";a:2:{s:3:"par";s:4:"type";s:10:"editmethod";s:27:"_Translator_edit_input_type";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"value";a:1:{s:3:"par";s:5:"value";}s:7:"checked";a:3:{s:3:"par";s:7:"checked";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:8:"readonly";a:3:{s:3:"par";s:8:"readonly";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:9:"maxlength";a:1:{s:3:"par";s:9:"maxlength";}s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:3:"alt";a:1:{s:3:"par";s:3:"alt";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:8:"tabindex";a:1:{s:3:"par";s:8:"tabindex";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:8:"onselect";a:1:{s:3:"par";s:8:"onselect";}s:8:"onchange";a:1:{s:3:"par";s:8:"onchange";}s:6:"accept";a:1:{s:3:"par";s:6:"accept";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:5:"shape";a:1:{s:3:"par";s:5:"shape";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:5:"label";a:7:{s:3:"tag";s:5:"label";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:5:"Label";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:5:"label";}}s:4:"pars";a:20:{s:3:"for";a:1:{s:3:"par";s:3:"for";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:6:"select";a:8:{s:3:"tag";s:6:"select";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"edittagsbefore";s:6:"select";s:14:"pictureforedit";s:19:"tags/tag_select.gif";s:7:"comment";s:6:"Select";s:7:"closeon";a:2:{s:5:"notin";a:1:{i:0;s:6:"option";}s:2:"in";a:1:{i:0;s:6:"select";}}s:4:"pars";a:24:{s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:8:"multiple";a:3:{s:3:"par";s:8:"multiple";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:6:"option";a:7:{s:3:"tag";s:6:"option";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";}s:2:"in";a:2:{i:0;s:6:"option";i:1;s:6:"option";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:6:"Option";s:4:"pars";a:20:{s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"value";a:1:{s:3:"par";s:5:"value";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:8:"selected";a:3:{s:3:"par";s:8:"selected";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}}}s:4:"link";a:4:{s:3:"tag";s:4:"link";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:17:"tags/tag_link.gif";s:4:"pars";a:13:{s:3:"rel";a:1:{s:3:"par";s:3:"rel";}s:3:"rev";a:1:{s:3:"par";s:3:"rev";}s:4:"href";a:1:{s:3:"par";s:4:"href";}s:6:"target";a:1:{s:3:"par";s:6:"target";}s:5:"media";a:1:{s:3:"par";s:5:"media";}s:8:"hreflang";a:1:{s:3:"par";s:8:"hreflang";}s:7:"charset";a:1:{s:3:"par";s:7:"charset";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}}}s:21:"EDIT_TAGS_AFTER_TABLE";a:2:{i:0;s:4:"body";i:1;s:2:"td";}}
\ No newline at end of file diff --git a/includes/htmlparser/htmlgrammar.dat b/includes/htmlparser/htmlgrammar.dat new file mode 100755 index 0000000..8329ad8 --- /dev/null +++ b/includes/htmlparser/htmlgrammar.dat @@ -0,0 +1,1176 @@ +/* +Îïèñàíèå ïàðàìåòðîâ ãðàììàòèêè +The grammar parameters description. + +endtag= "present | canabsent | absent" + present - çàêðûòèå òåãà îáÿçàòåëüíî äîëæíî ïðèñóòñòâîâàòü + - close tag must present + + canabsent - çàêðûòèå òåãà ìîæåò îòñóòñòâîâàòü, íî ìîæåò è ïðèñóòñòâîâàòü + - close tag can absent + + absent - çàêðûòèå òåãà âñåãäà îòñóòñòâóåò + - close tag always absent + +nohavesametag - òýã íå ìîæåò ñîäåðæàòü â ñåáå ñåáÿ ñàìîãî, åñëè âíóòðè òýãà âñòðå÷àåòñÿ + îí ñàì, òî òåã çàêðûâàåòñÿ + - tag can't contains itself inside. If it has itself inside then it must + be closed before itself + +nohavetags - òåã ñîäåðæèò òîëüêî òåêñò. Äàæå åñëè âíóòðè íåãî âñòðå÷àþòñÿ òýãè, òî + îíè òðàêòóþòñÿ êàê òåêñò. + - tag can has text only. If it has tags inside then these tags will be to interpret + as text. + +closeon = - "tagname|...|!tagname|..." - ïðèíóäèòåëüíîå çàêðûòèå òýãà ïðè âñòðå÷å îòêðûòèÿ + äðóãîãî òåãà. ìîæíî äåëàòü ïåðå÷èñëåíèÿ ìíîæåñòâà òåãîâ èëè îòðèöàíèå ìíîæåñòâà + òåãîâ, íàïðèìåð closeon="a|b|i|!form" òî åñòü çàêðûâàòü òåã ïðè âñòðå÷å îòêðûòèÿ + òåãîâ A,B,I è åñëè ýòî ê òîìó æå íå òåã FORM + - "tagname|...|!tagname|..." - rules for closing tag. |tagname|... list says + that tag must to be closed before first tagname if it exist inside it. + |!tagname|!.... list says then tag must to be closed if it has not a tagname + tag inside. You must combine these lists into one closeon part. For example: + closeon="a|b|i|!form" or closeon="a" or closeon="!form". + +Âû òàêæå ìîæåòå äîáàâëÿòü ñâîè ïàðàìåòðû â ãðàììàòèêó åñëè Âàì íàäî èñïîëüçîâàòü èõ â äàëüíåéøåì. +Íàïðèìåð, Âàì íàäî óêàçàòü êàêîé ôóíêöèåé âû áóäåòå îáðàáàòûâàòü òåã óæå ïîñëå ïàðñèíãà +òîãäà ïèøèòå, íàïðèìåð, function="MyFunction". +À ïîñëå ïðîöåññà ïàðñèíãà êîäà, ïðîáåãàÿ ïî äåðåâó òýãîâ çàãëÿäûâàåòå â ãðàììàòèêó ýòîãî òåãà +è, íàïðèìåð, âûçûâàåòå äëÿ íåãî ôóíêöèþ ñ ýòèì èìåíåì. +Òî÷íî òàê æå ìîæíî äîáàâëÿòü ïàðàìåòðû â îïèñàíèå ïàðàìåòðîâ òåãîâ. + +You can add your own parameters into grammar if it needs. For example, you need walk +through parsed grammar tree and if you meet someone tag you need process it by someone function. +In this case you can add special parameter for this tag, for example: function="MyFunction" and +after HTML parse process you will be walk through HTML tree and see into +grammar when you meet tag, and if it has function field you will call function by name in this field for this tag. +Using the same method you can add own parameter fields on tag parameters into grammar. + +I used this grammar in my HTML tag visualizer and you can see my additional parameter +"editmethod" for this with function names which I called in my visualizer. +you can see my additional parameter "pictureforedit" too. It needs for the pictogram for each tag. +I used so "width" and "height" additional parameters for visualize fields of tag with certain +width and height. + +BUT THESE ADDITIONAL PARAMETERS NOT NEEDS FOR HTML PARSER! IT WILL NEED AFTER ONLY! FOR +MY SPECIAL NEEDS. + +Ïðåêîìïèëåíàÿ ãðàììàòèêà èìååò ñëåäóþùóþ ñòðóêòóðó: +structure of precompiled grammar is: + +array( + "tagname"=>array( + "internal parameter name"=>value, + ..... + "pars"=>array( + "parname"=>array( + "parparameter name"=>value, + ..... + ), + ..... + ) + ) + .... +) +íàïðèìåð, ó âàñ â îòïàðñåíîì äåðåâå åñòü òåã <a ...>. Åãî ïîëíûé íàáîð ïàðàìåòðîâ +â ïðåêîìïèëåíîé ãðàììàòèêå $grammar ìîæíî ïîñìîòðåòü ñëåäóþùèì îáðàçîì + +For example, if you have tag A into parsed tree, then you can see the +grammar for A tag as + +PrintArray($grammar["a"]) + +à òîëüêî íàáîð ïàðàìåòðîâ òåãà, íàïðèìåð òàê + +and parameters only for tag A as + +PrintArray($grammar["a"]["pars"]) +*/ + +<tag="pre" + endtag="present" + nohavetags +> +<tag="hr" + endtag="absent" + [ par="color" ] + [ par="width" ] + [ par="noshade" single editmethod="_Translator_edit_standart_single_control"] +> + +<tag="noframes" + endtag="present" +> + +<tag="frameset" + endtag="canabsent" + pictureforedit="tags/tag.gif" + [ par=rows ] + [ par=cols ] + [ par=frameborder ] + [ par=border ] + [ par=framespacing ] + [ par=marginheight ] + [ par=marginwidth ] + [ par=noresize ] +> + +<tag="frame" + endtag="absent" + pictureforedit="tags/tag_frame2.gif" + [ par=name ] + [ par=target ] + [ par=scrolling ] + [ par=border ] + [ par=frameborder ] + [ par=framespacing ] + [ par=marginheight ] + [ par=marginwidth ] + [ par=noresize ] + [ par=src width="40" height="3" ] +> + +<tag="iframe" + pictureforedit="tags/tag_iframe2.gif" +> + +<tag="html" + endtag="present" + edittagsafter="body" + comment="Html" + pictureforedit="tags/tag.gif" +> + +<tag="meta" + endtag="absent" + edittagsafter="body" +> + +<tag="script" + nohavetags + endtag="present" + pictureforedit="tags/tag_script.gif" + edittagsbefore="script" + [ par="language" ] + [ par="src" width="40" height="3" ] +> + +<tag="nobr" + closeon="!strong|!sup|!center|!font|!i|!b|!u|!tt|!s|!big|!small|!strike|!br|!script" + endtag="present" +> + +<tag="p" +closeon="!a|!map|!area|!strong|!sup|!font|!i|!b|!u|!tt|!img|!s|!big|!small|!strike|!nobr|!br|!script|!input|!select|!textarea|!option|!button" + endtag="canabsent" + pictureforedit="tags/tag_p2.gif" + [ par="align" editmethod="_Translator_edit_p_align"] +> + +<tag="th" + endtag="absent" + [ par="align" editmethod="_Translator_edit_th_align"] +> + +<tag="noscript" + endtag="present" +> + +<tag="style" + nohavetags + endtag="present" +> + +<tag="head" + endtag="present" + edittagsafter="body" +> + +<tag="center" + endtag="present" + comment="Center" + pictureforedit="tags/tag.gif" +> + +<tag="img" + endtag="absent" + comment="Picture" + pictureforedit="tags/tag_img.gif" + [ par="src" width="40" height="3" ] + + [ par="alt" ] + [ par="width"] + [ par="height"] + [ par="border"] + [ par="name"] + [ par="align" editmethod="_Translator_edit_img_align"] + [ par="vspace" ] + [ par="hspace" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmouseover" ] + [ par="onmouseout" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="usemap" editmethod="_Translator_edit_standart_usemap"] +> +<tag="a" + nohavesametag + endtag="present" + edittagsbefore="a" + comment="Url" + pictureforedit="tags/tag_a.gif" + closeon="!strong|!sup|!center|!font|!i|!b|!u|!tt|!img|!s|!big|!small|!strike|!nobr|!br|!script|!li|!ol|!ul" + [ par="href" width="40" height="3" ] + [ par="name" ] + [ par="hreflang" ] + [ par="rel" ] + [ par="rev" ] + + [ par="id"] + [ par="class" ] + [ par="lang" ] + [ par="accesskey" ] + [ par="shape" ] + [ par="onfocus" ] + [ par="onblur" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="tabindex" ] + [ par="target"] +> + +<tag="ul" + endtag="present" + comment="Unsequence list" + pictureforedit="tags/tag.gif" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|!li|!ol|table|tr|td" + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir"] + [ par="title" ] + [ par="style" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="type" ] +> + +<tag="li" + endtag="present" + comment="List element" + pictureforedit="tags/tag.gif" + nohavesametag + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|!ol|!ul" + + [ par="value" ] + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="type" ] +> + +<tag="ol" + endtag="present" + comment="Sequence list" + pictureforedit="tags/tag.gif" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|!ol|!ul" + nohavesametag + + [ par="start" ] + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="type" ] +> + +<tag="title" + endtag="present" + comment="Page header" + pictureforedit="tags/tag.gif" +> + +<tag="textarea" + nohavetags + endtag="present" + comment="Textarea" + pictureforedit="tags/tag_textarea.gif" + + [ par="disabled" single editmethod="_Translator_edit_standart_single_control"] + [ par="name" ] + [ par="rows" ] + [ par="cols" ] + [ par="accesskey" ] + [ par="wrap" ] + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + + [ par="onfocus" ] + [ par="onblur" ] + [ par="onselect" ] + [ par="onchange" ] + + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="tr" + endtag="present" + comment="Table row" + pictureforedit="tags/tag_tr.gif" + edittagsafter="td" + + [ par="align" editmethod="_Translator_edit_td_align"] + [ par="valign" editmethod="_Translator_edit_td_valign"] + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="bgcolor" ] + [ par="background" ] + + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="td" + endtag="present" + comment="Table cell" + pictureforedit="tags/tag_td.gif" + edittagsafter="td" + + [ par="colspan" ] + [ par="rowspan" ] + [ par="width" ] + [ par="height" ] + [ par="bgcolor" ] + [ par="background" ] + [ par="align" editmethod="_Translator_edit_td_align" ] + [ par="valign" editmethod="_Translator_edit_td_valign" ] + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="nowrap" single editmethod="_Translator_edit_standart_single_control" ] +> + +<tag="table" + endtag="present" + comment="Table" + pictureforedit="tags/tag_table.gif" + + [ par="width" ] + [ par="height" ] + [ par="bgcolor" ] + [ par="background" ] + [ par="cellspacing" ] + [ par="cellpadding" ] + [ par="border" ] + [ par="bordercolor" ] + [ par="summary" ] + [ par="align" editmethod="_Translator_edit_table_align" ] + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypressed" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="area" endtag="absent" + pictureforedit="tags/tag.gif" + comment="Map region" + + [ par="href" width="40" height="3" ] + [ par="shape" editmethod="_Translator_edit_standart_shape" ] + [ par="coords" ] + [ par="usemap" ] + [ par="alt" ] + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="accesskey" ] + [ par="onfocus" ] + [ par="onblur" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="tabindex" ] +> + +<tag="span" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Span" + [ par="id" ] + [ par="class"] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="b" + nohavesametag + endtag="present" + pictureforedit="tags/tag_b2.gif" + comment="B" + [ par="id" ] + [ par="class"] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="tt" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="TT" + [ par="id"] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="i" + nohavesametag + endtag="present" + pictureforedit="tags/tag_i2.gif" + comment="I" + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="big" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Big" + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="small" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Small" + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="strike" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Strike" + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="s" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="S" + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="u" + nohavesametag + endtag="present" + pictureforedit="tags/tag_u2.gif" + comment="U" + [ par="id"] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="map" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Map" + closeon="!area" + [ par="name" ] +> + +<tag="br" + edit="0" + endtag="absent" + [ par="clear" ] + [ par="id" ] + [ par="title" ] + [ par="class" ] + [ par="style" ] +> +<tag="base" + endtag="absent" + pictureforedit="tags/tag.gif" + comment="Base" + [ par="href" width="40" height="3" ] + [ par="target" ] +> + +<tag="basefont" + endtag="absent" + pictureforedit="tags/tag.gif" + comment="Basefont" + [ par="id" ] + [ par="size" ] + [ par="color" ] + [ par="face" ] + [ par="class" ] + [ par="title" ] + [ par="style" ] +> + +<tag="body" + nohavesametag + endtag="present" + pictureforedit="tags/tag_body.gif" + edittagsafter="body" + comment="Page body" + + [ par="background" ] + [ par="text" ] + [ par="link" ] + [ par="vlink" ] + [ par="alink" ] + [ par="id" ] + [ par="class" ] + [ par="bgcolor" ] + [ par="style" ] + [ par="title" ] + [ par="lang" ] + [ par="style" ] + [ par="topmargin"] + [ par="leftmargin"] + [ par="marginwidth"] + [ par="marginheight"] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="onload" ] + [ par="onunload" ] +> + +<tag="button" + nohavesametag + endtag="present" + pictureforedit="tags/tag_button.gif" + comment="Button" + closeon="!center|!font|!i|!b|!u|!tt|!a|!img|!s|!big|!small|!strike|!nobr|!br|!script" + + [ par="name" ] + [ par="value" ] + [ par="type" ] + [ par="disabled" single editmethod="_Translator_edit_standart_single_control"] + [ par="accesskey" ] + [ par="usemap" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="onfocus" ] + [ par="onblur" ] +> + +<tag="div" + endtag="present" + pictureforedit="tags/tag_div.gif" + comment="Division" + + [ par="id" ] + [ par="name" ] + [ par="class" ] + [ par="align" editmethod="_Translator_edit_div_align"] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="span" + endtag="present" + pictureforedit="tags/tag.gif" + comment="span" + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="font" + endtag="present" + pictureforedit="tags/tag_font2.gif" + comment="Font" + closeon="!i|!b|!u|!tt|!a|!img|!s|!big|!small|!strike|!nobr|!br|!script" + + [ par="id" ] + [ par="size" ] + [ par="color" ] + [ par="face" ] + [ par="class" ] + [ par="title" ] + [ par="style" ] + [ par="lang" ] + [ par="dir" ] +> + +<tag="form" + endtag="present" + pictureforedit="tags/tag_form.gif" + comment="Form" + + [ par="action" width="40" height="3"] + [ par="method" ] + [ par="enctype" ] + [ par="accept-charset" ] + [ par="accept" ] + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="style" ] + [ par="title" ] + [ par="target" ] + [ par="onsubmit" ] + [ par="onreset" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="h1" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="hl" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script" + [ par="id" ] + [ par="class"] + [ par="lang"] + [ par="dir"] + [ par="style"] + [ par="title"] + [ par="align"] + [ par="onclick"] + [ par="ondblclick"] + [ par="onmousedown"] + [ par="onmouseup"] + [ par="onmouseover"] + [ par="onmousemove"] + [ par="onmouseout"] + [ par="onkeypress"] + [ par="onkeydown"] + [ par="onkeyup"] +> +<tag="h2" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="h2" + [ par="id" ] + [ par="class"] + [ par="lang"] + [ par="dir"] + [ par="style"] + [ par="title"] + [ par="align"] + [ par="onclick"] + [ par="ondblclick"] + [ par="onmousedown"] + [ par="onmouseup"] + [ par="onmouseover"] + [ par="onmousemove"] + [ par="onmouseout"] + [ par="onkeypress"] + [ par="onkeydown"] + [ par="onkeyup"] +> +<tag="h3" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="h3" + [ par="id" ] + [ par="class"] + [ par="lang"] + [ par="dir"] + [ par="style"] + [ par="title"] + [ par="align"] + [ par="onclick"] + [ par="ondblclick"] + [ par="onmousedown"] + [ par="onmouseup"] + [ par="onmouseover"] + [ par="onmousemove"] + [ par="onmouseout"] + [ par="onkeypress"] + [ par="onkeydown"] + [ par="onkeyup"] +> +<tag="h4" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="h4" + [ par="id" ] + [ par="class"] + [ par="lang"] + [ par="dir"] + [ par="style"] + [ par="title"] + [ par="align"] + [ par="onclick"] + [ par="ondblclick"] + [ par="onmousedown"] + [ par="onmouseup"] + [ par="onmouseover"] + [ par="onmousemove"] + [ par="onmouseout"] + [ par="onkeypress"] + [ par="onkeydown"] + [ par="onkeyup"] +> +<tag="h5" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="h5" + [ par="id" ] + [ par="class"] + [ par="lang"] + [ par="dir"] + [ par="style"] + [ par="title"] + [ par="align"] + [ par="onclick"] + [ par="ondblclick"] + [ par="onmousedown"] + [ par="onmouseup"] + [ par="onmouseover"] + [ par="onmousemove"] + [ par="onmouseout"] + [ par="onkeypress"] + [ par="onkeydown"] + [ par="onkeyup"] +> +<tag="h6" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="h6" + [ par="id" ] + [ par="class"] + [ par="lang"] + [ par="dir"] + [ par="style"] + [ par="title"] + [ par="align"] + [ par="onclick"] + [ par="ondblclick"] + [ par="onmousedown"] + [ par="onmouseup"] + [ par="onmouseover"] + [ par="onmousemove"] + [ par="onmouseout"] + [ par="onkeypress"] + [ par="onkeydown"] + [ par="onkeyup"] +> + +<tag="input" + endtag="absent" + pictureforedit="tags/tag_input.gif" + comment="Form input element" + + [ par="type" editmethod="_Translator_edit_input_type" ] + [ par="name" ] + [ par="value" ] + [ par="checked" single editmethod="_Translator_edit_standart_single_control" ] + [ par="disabled" single editmethod="_Translator_edit_standart_single_control" ] + [ par="readonly" single editmethod="_Translator_edit_standart_single_control" ] + [ par="size" ] + [ par="maxlength" ] + [ par="src" width="40" height="3" ] + [ par="width"] + [ par="height"] + [ par="alt" ] + [ par="border"] + [ par="tabindex"] + [ par="accesskey"] + [ par="onfocus" ] + [ par="onblur" ] + [ par="onselect"] + [ par="onchange"] + [ par="accept" ] + + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="align" ] + [ par="shape" ] + [ par="onfocus" ] + [ par="onblur" ] + [ par="onclick" ] + [ par="onselect" ] + [ par="onchange" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="label" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Label" + + [ par="for" ] + [ par="accesskey" ] + [ par="onfocus" ] + [ par="onblur" ] + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="select" + nohavesametag + endtag="present" + edittagsbefore="select" + pictureforedit="tags/tag_select.gif" + comment="Select" + closeon="!option" + + [ par="disabled" single editmethod="_Translator_edit_standart_single_control" ] + [ par="multiple" single editmethod="_Translator_edit_standart_single_control" ] + [ par="name" ] + [ par="size" ] + [ par="width" ] + [ par="accesskey" ] + [ par="onfocus" ] + [ par="onblur" ] + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] +> + +<tag="option" + closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|option" + nohavesametag + endtag="present" + pictureforedit="tags/tag.gif" + comment="Option" + + [ par="name" ] + [ par="value" ] + [ par="accesskey" ] + [ par="id" ] + [ par="class" ] + [ par="lang" ] + [ par="dir" ] + [ par="title" ] + [ par="style" ] + [ par="onclick" ] + [ par="ondblclick" ] + [ par="onmousedown" ] + [ par="onmouseup" ] + [ par="onmouseover" ] + [ par="onmousemove" ] + [ par="onmouseout" ] + [ par="onkeypress" ] + [ par="onkeydown" ] + [ par="onkeyup" ] + [ par="selected" single editmethod="_Translator_edit_standart_single_control"] +> + +<tag="link" + endtag="absent" + pictureforedit="tags/tag_link.gif" + [ par=rel ] + [ par=rev ] + [ par=href ] + [ par=target ] + [ par=media ] + [ par=hreflang ] + [ par=charset ] + [ par=title ] + [ par=dir ] + [ par=lang ] + [ par=style ] + [ par=id ] + [ par=class ] +> diff --git a/includes/htmlparser/htmlgrammarparser.inc b/includes/htmlparser/htmlgrammarparser.inc new file mode 100755 index 0000000..259fcce --- /dev/null +++ b/includes/htmlparser/htmlgrammarparser.inc @@ -0,0 +1,478 @@ +<?php +if (!defined("_ECHOSERVER_HTML_GRAMMARPARSER")) { +define("_ECHOSERVER_HTML_GRAMMARPARSER",1); + +class HtmlGrammarParser { + var $line, + $column, + $pos, + $length, + $data, + $pg, + $pgpos, + $parpos, + $incomment, + $name, + $allreadyparsed, + $errors, + $errpos, + $quotstate, + $firstprev, + $secondprev, + $firststate, + $secondstate, + $iseof, + $mode, + $tagname, + $parname; +/********************************************************************************** + * Class constructor + **********************************************************************************/ + function HtmlGrammarParser($data) { + $this->firstprev=array("state"=>0,"word"=>""); + $this->secondprev=array("state"=>0,"word"=>""); + $this->line=0; + $this->pos=0; + $this->errors=array(); + $this->errpos=-1; + $this->incomment=-1; + $this->allreadyparsed=0; + $this->pg=array(); + $this->pgpos=-1; + $this->quotstate=-1; + $this->iseof=false; + $this->firststate=0; + $this->secondstate=0; + $this->mode=1; + + if(gettype($this->data)=="array") { + $this->pg=&$data; + $this->allreadyparsed=1; + return; + } + clearstatcache(); + $this->name=$data; + if (!file_exists($this->name)) { + $this->SetError(1,"File $this->name not exists.",0,0,"Error"); + return; + } + if (!$fp=fopen($this->name,"r")) { + $this->SetError(1,"Can't open file $this->name.",0,0,"Error"); + return; + } + flock($fp,1); + $this->data=fread($fp,filesize($this->name)); + flock($fp,3); + fclose($fp); + $this->length=strlen($this->data); + } + +/******************************************************************************************** + * Store parser's errors and warnings + ********************************************************************************************/ + function SetError($e,$str,$line=0,$column=0,$errtype="Warning") { + $this->errors[++$this->errpos]["type"]=$errtype; + $this->errors[$this->errpos]["code"]=$e; + $this->err=$e; + $this->errstr="<b>$errtype:</b> $e, $str"; + if ($line) { + if (strlen($this->name)) + $this->errstr.="object <font color=\"red\">$this->name</font>"; + $this->errstr.=" Line <b>$line</b>, Column <b>$column</b>"; + } + $this->errors[$this->errpos]["str"]=$this->errstr."<br>\r\n"; + } + +/******************************************************************************************** + * Print parser's errors and warnings + ********************************************************************************************/ + function PrintErrors() { + for ($i=0;$i<=$this->errpos;$i++) + print $this->errors[$i]["str"]; + } + +/******************************************************************************************** + * Get word from data + ********************************************************************************************/ + function GetWord($word) { + $word=""; + $found=0; + $iter=0; + if ($this->pos>$this->length) + return false; + while (!$found) { + if ($this->pos>$this->length) + return false; + if ($this->pos==$this->length) { + $this->pos++; + return $word; + } + switch($this->data[$this->pos]) { + case "*": + if ($this->quotstate==1) { + $word.=$this->data[$this->pos++]; + $this->column++; + break; + } + $this->column++; + $this->pos++; + if ($word[0]=="/") + $found=1; + $word.=$this->data[$this->pos-1]; + break; + case "/": + if ($this->quotstate==1) { + $word.=$this->data[$this->pos++]; + $this->column++; + break; + } + $this->column++; + $this->pos++; + if ($word[0]=="*") + $found=1; + $word.=$this->data[$this->pos-1]; + break; + case " ": + case "\r": + case "\t": + if ($this->quotstate==1) { + $word.=$this->data[$this->pos++]; + $this->column++; + break; + } + $this->column++; + $this->pos++; + if (strlen($word)) + $found=1; + break; + case "\n": + if ($this->quotstate==1) { + $word.=$this->data[$this->pos++]; + $this->column++; + break; + } + $this->column=0; + $this->line++; + $this->pos++; + if (strlen($word)) + $found=1; + break; + case ">": + case "<": + case "=": + if ($this->quotstate==1) { + $word.=$this->data[$this->pos++]; + $this->column++; + } else { + if (!strlen($word)) { + $word=$this->data[$this->pos++]; + $this->column++; + } + $found=1; + } + break; + case "\"": + if ($this->pos) { + if ($this->data[$this->pos-1]=="\\") { + $word.=$this->data[$this->pos++]; + $this->column++; + } else { + if (!strlen($word)) { + $this->quotstate*=-1; + $word=$this->data[$this->pos++]; + $this->column++; + } + $found=1; + } + } else { + $word=$this->data[$this->pos++]; + $this->column++; + $found=1; + } + break; + default: + $this->column++; + $word.=$this->data[$this->pos++]; + } + } + return true; + } + +/******************************************************************************************** + * Parse grammar first step + ******************************************************************************************** +Parse +< [] [] > + +in/state 0 1 2 3 +< 1 -1 -1 1 +[ -1 2 -1 -1 +] -1 -1 1 -1 +> -1 3 -1 -1 +word -1 1 2 -1 +EOF -1 -1 -1 -2 + +-2 end parse + 0 begin parse, waiting '<' + 1 got '<' need to parse parameters, or wait '>' or wait '[' + 2 got '[' or ']' need to parse parameters + 3 got '>', waiting eof or '<' + + ********************************************************************************************/ + function ParseFirst($word) { + if ($this->iseof) { + $this->firstprev["state"]=0; + $this->firstprev["word"]=""; + return true; + } + $automat=array( + "0"=>array( 1, -1, -1, 1), + "1"=>array(-1, 2, -1, -1), + "2"=>array(-1, -1, 1, -1), + "3"=>array(-1, 3, -1, -1), + "4"=>array(-1, 1, 2, -1), + "5"=>array(-1, -1, -1, -2) + ); + switch($word) { + case "<": + $instate=0; + $this->pgpos++; + $this->parpos=-1; + break; + case "[": + $this->parpos++; + $instate=1; + break; + case "]": + $instate=2; + break; + case ">": + $instate=3; + break; + default: + $instate=4; + break; + } + $this->firststate=$automat[$instate][$this->firststate]; + if ($this->firststate==-1) return false; + switch ($this->firststate) { + case 1: + $this->mode=1; + if ($this->firstprev["state"]==1) + if (!$this->ParseSecond($word)) return false; + break; + case 2: + switch($this->firstprev["state"]) { + case 1: + $this->mode=2; + break; + case 3: + case 2: + if ($this->firstprev["state"]==2) + $this->mode=2; + else + $this->mode=1; + break; + } + if ($this->firstprev["state"]==2) + if (!$this->ParseSecond($word)) return false; + break; + case 3: + if (isset($this->pg[$this->pgpos]["tag"]["nohavesametag"])) + $this->pg[$this->pgpos]["tag"]["closeon"]["in"][]=$this->tagname; + break; + } + $this->firstprev["state"]=$this->firststate; + $this->firstprev["word"]=$word; + return true; + } + +/******************************************************************************************** + * Parse grammar second step + ******************************************************************************************** + +Parse +par1="value" par2=value + +in/state 0 1 2 3 4 += -1 2 -1 3 -1 +" -1 -1 3 4 -1 +word 1 -1 4 3 1 +EOF -1 -1 -1 -1 -1 + +-3 end parse by '>' +-2 end parse by ']' + 0 begin parse waiting parname + 1 got parname, waiting '=' or new parname + 2 got '=' waiting any word as value or first '"' + 3 collect words to next '"' + 4 got parvalue, waiting new parname + ********************************************************************************************/ + function ParseSecond($word) { + if ($this->iseof) return false; + $automat=array( + "0"=>array(-1, 2, -1, 3, -1), + "1"=>array(-1, -1, 3, 4, -1), + "2"=>array( 1, 1, 4, 3, 1), + "3"=>array(-1, -1, -1, -1, -1) + ); + switch($word) { + case "=": + $instate=0; + break; + case "\"": + $instate=1; + break; + default: + $instate=2; + break; + } + $this->secondstate=$automat[$instate][$this->secondstate]; + if ($this->secondstate==-1) return false; + switch ($this->secondstate) { + case 1: + $this->parname=$word; + if (!ereg("[a-zA-Z_-]+([0-9]+)?",$word)) { + $this->SetError(1,"Fatal error.",$this->line,$this->column,"Error"); + return false; + } + switch($this->mode) { + case 1: + $this->pg[$this->pgpos]["tag"][$this->parname]=""; + break; + case 2: + $this->pg[$this->pgpos]["pars"][$this->parpos][$this->parname]=""; + break; + } + break; + case 4: + switch($this->mode) { + case 1: + if ($this->secondprev["state"]==3) + $this->pg[$this->pgpos]["tag"][$this->parname]=$this->secondprev["word"]; + else + $this->pg[$this->pgpos]["tag"][$this->parname]=$word; + if ($this->parname=="closeon") { + $notexists=array(); + $exists=array(); + $this->ParseCloseOn($this->pg[$this->pgpos]["tag"][$this->parname],&$notexists,&$exists); + $this->pg[$this->pgpos]["tag"][$this->parname]=array(); + $this->pg[$this->pgpos]["tag"][$this->parname]["notin"]=$notexists; + $this->pg[$this->pgpos]["tag"][$this->parname]["in"]=$exists; + } elseif ($this->parname=="tag") + $this->tagname=$this->pg[$this->pgpos]["tag"]["tag"]; + break; + case 2: + if ($this->secondprev["state"]==3) + $this->pg[$this->pgpos]["pars"][$this->parpos][$this->parname]=$this->secondprev["word"]; + else + $this->pg[$this->pgpos]["pars"][$this->parpos][$this->parname]=$word; + break; + } + break; + } + $this->secondprev["state"]=$this->secondstate; + $this->secondprev["word"]=$word; + return true; + } + +/******************************************************************************************** + * Parse closeon structure + ********************************************************************************************/ + function ParseCloseOn($str,$notexists,$exists) { + $arr=explode("|",$str); + if (!is_array($arr)) { + if (!strlen($str)) + return; + else + $arr[]=$str; + } + for ($i=0;$i<sizeof($arr);$i++) { + if ($arr[$i][0]=="!") + $notexists[]=substr($arr[$i],1,strlen($arr[$i])-1); + else + $exists[]=$arr[$i]; + } + } + +/******************************************************************************************** + * Parse grammar + ********************************************************************************************/ + function Parse() { + if ($this->allreadyparsed) return true; + $this->line=1; + while(1) { + $isword=$this->GetWord(&$word); + if (!$isword) $this->iseof=true; + switch (strtolower($word)) { + case "/*"; + $this->incomment*=-1; + break; + case "*/"; + if ($this->incomment!=1) { + $this->SetError(1,"Not found begin of comment operator.",$this->line,$this->column,"Error"); + return; + } + $this->incomment*=-1; + break; + default: + if ($this->incomment==1) break; + if (!$this->ParseFirst($word)) { + $this->SetError(1,"Fatal error",$this->line,$this->column,"Error"); + return false; + } + break; + } + if ($this->iseof) break; + } + if ($this->incomment==1) { + $this->SetError(1,"Not found end of comment operator.",$this->line,$this->column,"Error"); + return false; + } + $this->PrepareGrammar(); + return true; + } +/******************************************************************************************** + * Prepare grammar for future using + ********************************************************************************************/ + function PrepareGrammar() { + $edittagsaftertable=$this->ScanGrammar(); + $l=sizeof($this->pg); + for ($i=0;$i<$l;$i++) { + $this->pg[$this->pg[$i]["tag"]["tag"]]=$this->pg[$i]["tag"]; + if (isset($this->pg[$i]["pars"])) { + $n=sizeof($this->pg[$i]["pars"]); + for ($j=0;$j<$n;$j++) + $this->pg[$this->pg[$i]["tag"]["tag"]]["pars"][$this->pg[$i]["pars"][$j]["par"]]=$this->pg[$i]["pars"][$j]; + } else + $this->pg[$this->pg[$i]["tag"]["tag"]]["pars"]=array(); + unset($this->pg["$i"]); + } + $this->pg["EDIT_TAGS_AFTER_TABLE"]=$edittagsaftertable; + } +/******************************************************************************************** + * Scan grammar for creating edittagsafter table + ********************************************************************************************/ + function ScanGrammar() { + $edittagsaftertable=array(); + for ($i=0;$i<sizeof($this->pg);$i++) + if (isset($this->pg[$i]["tag"]["edittagsafter"])) + if (!in_array($this->pg[$i]["tag"]["edittagsafter"],$edittagsaftertable)) $edittagsaftertable[]=$this->pg[$i]["tag"]["edittagsafter"]; + return $edittagsaftertable; + } +/******************************************************************************************** + * Save precompiled grammar in file + ********************************************************************************************/ + function SaveGrammar($name) { + $str=serialize($this->pg); + if (!$fp=fopen($name,"w")) + print "<br>Error: Can't create file $name. Unable to save grammar.<br>"; + flock($fp,2); + fwrite($fp,$str,strlen($str)); + flock($fp,3); + fclose($fp); + } +} + +} //_ECHOSERVER_HTML_GRAMMARPARSER +?> diff --git a/includes/htmlparser/readme.eng.txt b/includes/htmlparser/readme.eng.txt new file mode 100755 index 0000000..96a9da1 --- /dev/null +++ b/includes/htmlparser/readme.eng.txt @@ -0,0 +1,19 @@ +testhtmlparser.php - example of using +rebuildgrammar.php - grammar compiler +htmlgrammar.dat - grammar +htmlgrammar.cmp - compiled grammar +test.html - html file for test the html parser +common.inc - additional functions +imgsrcchange.inc - this example shows how to change src parameter for all img tags. + +Setup is very simple. You need copy all files into someone catalog on +your web server and after this call http://..../testhtmlparser.php +As result you will have start page of Russian PHPClub site which placed into the test.html file. +This page was formed by tag's tree after parse process. Bellow you can see +printed tag's tree. + +All questions you can send to +anton@concord.ru + +or by ICQ +3180528 diff --git a/includes/htmlparser/rebuildgrammar.php b/includes/htmlparser/rebuildgrammar.php new file mode 100755 index 0000000..9b5bdbb --- /dev/null +++ b/includes/htmlparser/rebuildgrammar.php @@ -0,0 +1,13 @@ +<?php + +//include ("common.inc"); + +include ("htmlgrammarparser.inc"); +$p = new HtmlGrammarParser("htmlgrammar.dat"); +$p->Parse(); +$p->PrintErrors(); +$p->SaveGrammar("htmlgrammar.cmp"); +print "Done."; +//PrintArray($p->pg); + +?> diff --git a/includes/tar.class.php b/includes/tar.class.php new file mode 100755 index 0000000..a0589d6 --- /dev/null +++ b/includes/tar.class.php @@ -0,0 +1,467 @@ +<?php +/* +======================================================================= +Name: + tar Class +Author: + Josh Barger <joshb@npt.com> +Description: + This class reads and writes Tape-Archive (TAR) Files and Gzip + compressed TAR files, which are mainly used on UNIX systems. + This class works on both windows AND unix systems, and does + NOT rely on external applications!! Woohoo! +Usage: + Copyright (C) 2002 Josh Barger + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details at: + http://www.gnu.org/copyleft/lesser.html + If you use this script in your application/website, please + send me an e-mail letting me know about it :) +Bugs: + Please report any bugs you might find to my e-mail address + at joshb@npt.com. If you have already created a fix/patch + for the bug, please do send it to me so I can incorporate it into my release. +Version History: + 1.0 04/10/2002 - InitialRelease + 2.0 04/11/2002 - Merged both tarReader and tarWriter + classes into one + - Added support for gzipped tar files + Remember to name for .tar.gz or .tgz + if you use gzip compression! + :: THIS REQUIRES ZLIB EXTENSION :: + - Added additional comments to + functions to help users + - Added ability to remove files and + directories from archive + 2.1 04/12/2002 - Fixed serious bug in generating tar + - Created another example file + - Added check to make sure ZLIB is + installed before running GZIP + compression on TAR + 2.2 05/07/2002 - Added automatic detection of Gzipped + tar files (Thanks go to Jrgen Falch + for the idea) + - Changed "private" functions to have + special function names beginning with + two underscores +======================================================================= +*/ +class tar { + // Unprocessed Archive Information + public $filename; + public $isGzipped; + public $tar_file; + // Processed Archive Information + public $files; + public $directories; + public $numFiles = 0; + public $numDirectories = 0; + // Class Constructor -- Does nothing... + function tar() { + return true; + } + // Computes the unsigned Checksum of a file's header + // to try to ensure valid file + // PRIVATE ACCESS FUNCTION + function __computeUnsignedChecksum($bytestring) { + $unsigned_chksum=0; + for($i=0; $i<512; $i++) + $unsigned_chksum += ord($bytestring[$i]); + for($i=0; $i<8; $i++) + $unsigned_chksum -= ord($bytestring[148 + $i]); + $unsigned_chksum += ord(" ") * 8; + return $unsigned_chksum; + } + // Converts a NULL padded string to a non-NULL padded string + // PRIVATE ACCESS FUNCTION + function __parseNullPaddedString($string) { + $position = strpos($string,chr(0)); + return substr($string,0,$position); + } + // This function parses the current TAR file + // PRIVATE ACCESS FUNCTION + function __parseTar() { + // Read Files from archive + $tar_length = strlen($this->tar_file); + $main_offset = 0; + while($main_offset < $tar_length) { + // If we read a block of 512 nulls, we are at the end of the archive + if(substr($this->tar_file,$main_offset,512) == str_repeat(chr(0),512)) + break; + // Parse file name + $file_name = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset,100)); + // Parse the file mode + $file_mode = substr($this->tar_file,$main_offset + 100,8); + // Parse the file user ID + $file_uid = octdec(substr($this->tar_file,$main_offset + 108,8)); + // Parse the file group ID + $file_gid = octdec(substr($this->tar_file,$main_offset + 116,8)); + // Parse the file size + $file_size = octdec(substr($this->tar_file,$main_offset + 124,12)); + // Parse the file update time - unix timestamp format + $file_time = octdec(substr($this->tar_file,$main_offset + 136,12)); + // Parse Checksum + $file_chksum = octdec(substr($this->tar_file,$main_offset + 148,6)); + // Parse user name + $file_uname = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 265,32)); + // Parse Group name + $file_gname = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 297,32)); + // Make sure our file is valid + if($this->__computeUnsignedChecksum(substr($this->tar_file,$main_offset,512)) != $file_chksum) + return false; + // Parse File Contents + $file_contents = substr($this->tar_file,$main_offset + 512,$file_size); + /* ### Unused Header Information ### + $activeFile["typeflag"] = substr($this->tar_file,$main_offset + 156,1); + $activeFile["linkname"] = substr($this->tar_file,$main_offset + 157,100); + $activeFile["magic"] = substr($this->tar_file,$main_offset + 257,6); + $activeFile["version"] = substr($this->tar_file,$main_offset + 263,2); + $activeFile["devmajor"] = substr($this->tar_file,$main_offset + 329,8); + $activeFile["devminor"] = substr($this->tar_file,$main_offset + 337,8); + $activeFile["prefix"] = substr($this->tar_file,$main_offset + 345,155); + $activeFile["endheader"] = substr($this->tar_file,$main_offset + 500,12); + */ + if($file_size > 0) { + // Increment number of files + $this->numFiles++; + // Create us a new file in our array + $activeFile = &$this->files[]; + // Asign Values + $activeFile["name"] = $file_name; + $activeFile["mode"] = $file_mode; + $activeFile["size"] = $file_size; + $activeFile["time"] = $file_time; + $activeFile["user_id"] = $file_uid; + $activeFile["group_id"] = $file_gid; + $activeFile["user_name"] = $file_uname; + $activeFile["group_name"] = $file_gname; + $activeFile["checksum"] = $file_chksum; + $activeFile["file"] = $file_contents; + } else { + // Increment number of directories + $this->numDirectories++; + // Create a new directory in our array + $activeDir = &$this->directories[]; + // Assign values + $activeDir["name"] = $file_name; + $activeDir["mode"] = $file_mode; + $activeDir["time"] = $file_time; + $activeDir["user_id"] = $file_uid; + $activeDir["group_id"] = $file_gid; + $activeDir["user_name"] = $file_uname; + $activeDir["group_name"] = $file_gname; + $activeDir["checksum"] = $file_chksum; + } + // Move our offset the number of blocks we have processed + $main_offset += 512 + (ceil($file_size / 512) * 512); + } + return true; + } + // Read a non gzipped tar file in for processing + // PRIVATE ACCESS FUNCTION + function __readTar($filename="") { + // Set the filename to load + if(!$filename) + $filename = $this->filename; + // Read in the TAR file + $fp = fopen($filename,"rb"); + $this->tar_file = fread($fp,filesize($filename)); + fclose($fp); + if($this->tar_file[0] == chr(31) && $this->tar_file[1] == chr(139) && $this->tar_file[2] == chr(8)) { + if(!function_exists("gzinflate")) + return false; + $this->isGzipped = TRUE; + $this->tar_file = gzinflate(substr($this->tar_file,10,-4)); + } + // Parse the TAR file + $this->__parseTar(); + return true; + } + // Generates a TAR file from the processed data + // PRIVATE ACCESS FUNCTION + function __generateTAR() { + // Clear any data currently in $this->tar_file + unset($this->tar_file); + $this->tar_file=""; + // Generate Records for each directory, if we have directories + if($this->numDirectories > 0) { + foreach($this->directories as $key => $information) { + unset($header); + // Generate tar header for this directory + // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end + $header .= str_pad($information["name"],100,chr(0)); + $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct(0),11,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0); + $header .= str_repeat(" ",8); + $header .= "5"; + $header .= str_repeat(chr(0),100); + $header .= str_pad("ustar",6,chr(32)); + $header .= chr(32) . chr(0); + $header .= str_pad("",32,chr(0)); + $header .= str_pad("",32,chr(0)); + $header .= str_repeat(chr(0),8); + $header .= str_repeat(chr(0),8); + $header .= str_repeat(chr(0),155); + $header .= str_repeat(chr(0),12); + // Compute header checksum + $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT); + for($i=0; $i<6; $i++) { + $header[(148 + $i)] = substr($checksum,$i,1); + } + $header[154] = chr(0); + $header[155] = chr(32); + // Add new tar formatted data to tar file contents + $this->tar_file .= $header; + } + } + // Generate Records for each file, if we have files (We should...) + if($this->numFiles > 0) { + foreach($this->files as $key => $information) { + unset($header); + $header=""; + // Generate the TAR header for this file + // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end + $header .= str_pad($information["name"],100,chr(0)); + $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["size"]),11,"0",STR_PAD_LEFT) . chr(0); + $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0); + $header .= str_repeat(" ",8); + $header .= "0"; + $header .= str_repeat(chr(0),100); + $header .= str_pad("ustar",6,chr(32)); + $header .= chr(32) . chr(0); + $header .= str_pad($information["user_name"],32,chr(0)); // How do I get a file's user name from PHP? + $header .= str_pad($information["group_name"],32,chr(0)); // How do I get a file's group name from PHP? + $header .= str_repeat(chr(0),8); + $header .= str_repeat(chr(0),8); + $header .= str_repeat(chr(0),155); + $header .= str_repeat(chr(0),12); + // Compute header checksum + $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT); + for($i=0; $i<6; $i++) { + $header[(148 + $i)] = substr($checksum,$i,1); + } + $header[154] = chr(0); + $header[155] = chr(32); + // Pad file contents to byte count divisible by 512 + $file_contents = str_pad($information["file"],(ceil($information["size"] / 512) * 512),chr(0)); + // Add new tar formatted data to tar file contents + $this->tar_file .= $header . $file_contents; + } + } + // Add 512 bytes of NULLs to designate EOF + $this->tar_file .= str_repeat(chr(0),512); + return true; + } + // Open a TAR file + function openTAR($filename) { + // Clear any values from previous tar archives + //unset($this->filename); + $this->filename=""; + //unset($this->isGzipped); + $this->isGzipped=0; + //unset($this->tar_file); + $this->tar_file=0; + //unset($this->files); + $this->files=""; + //unset($this->directories); + //unset($this->numFiles); + //unset($this->numDirectories); + $this->directories=""; + $this->numFiles=0; + $this->numDirectories=0; + // If the tar file doesn't exist... + if(!file_exists($filename)) + return false; + $this->filename = $filename; + // Parse this file + $this->__readTar(); + return true; + } + // Appends a tar file to the end of the currently opened tar file + function appendTar($filename) { + // If the tar file doesn't exist... + if(!file_exists($filename)) + return false; + $this->__readTar($filename); + return true; + } + // Retrieves information about a file in the current tar archive + function getFile($filename) { + if($this->numFiles > 0) { + foreach($this->files as $key => $information) { + if($information["name"] == $filename) + return $information; + } + } + return false; + } + // Retrieves information about a directory in the current tar archive + function getDirectory($dirname) { + if($this->numDirectories > 0) { + foreach($this->directories as $key => $information) { + if($information["name"] == $dirname) + return $information; + } + } + return false; + } + // Check if this tar archive contains a specific file + function containsFile($filename) { + if($this->numFiles > 0) { + foreach($this->files as $key => $information) { + if($information["name"] == $filename) + return true; + } + } + return false; + } + // Check if this tar archive contains a specific directory + function containsDirectory($dirname) { + if($this->numDirectories > 0) { + foreach($this->directories as $key => $information) { + if($information["name"] == $dirname) + return true; + } + } + return false; + } + // Add a directory to this tar archive + function addDirectory($dirname) { + if(!file_exists($dirname)) + return false; + // Get directory information + $file_information = stat($dirname); + // Add directory to processed data + $this->numDirectories++; + $activeDir = &$this->directories[]; + $activeDir["name"] = $dirname; + $activeDir["mode"] = $file_information["mode"]; + $activeDir["time"] = $file_information["time"]; + $activeDir["user_id"] = $file_information["uid"]; + $activeDir["group_id"] = $file_information["gid"]; + $activeDir["checksum"] = $checksum; + return true; + } + // Add a file to the tar archive + function addFile($filename) { + // Make sure the file we are adding exists! + if(!file_exists($filename)) + return false; + // Make sure there are no other files in the archive that have this same filename + if($this->containsFile($filename)) + return false; + // Get file information + $file_information = stat($filename); + // Read in the file's contents + $fp = fopen($filename,"rb"); + $file_contents = fread($fp,filesize($filename)); + fclose($fp); + // Add file to processed data + $this->numFiles++; + $activeFile = &$this->files[]; + $activeFile["name"] = $filename; + $activeFile["mode"] = $file_information["mode"]; + $activeFile["user_id"] = $file_information["uid"]; + $activeFile["group_id"] = $file_information["gid"]; + $activeFile["size"] = $file_information["size"]; + $activeFile["time"] = $file_information["mtime"]; + $activeFile["checksum"] = $checksum; + $activeFile["user_name"] = ""; + $activeFile["group_name"] = ""; + $activeFile["file"] = $file_contents; + return true; + } + // Add a file to the tar archive + function addData($filename,$data,$time=0) { + global $gBitSystem; + // Make sure there are no other files in the archive that have this same filename + if($this->containsFile($filename)) + return false; + if (!$time) $time=$gBitSystem->getUTCTime(); + // Read in the file's contents + $file_contents = $data; + // Add file to processed data + $this->numFiles++; + $activeFile = &$this->files[]; + $activeFile["name"] = $filename; + $activeFile["mode"] = octdec("666"); + $activeFile["user_id"] = ""; + $activeFile["group_id"] = ""; + $activeFile["size"] = strlen($data); + $activeFile["time"] = $time; + if(!isset($checksum)) $checksum=0; + $activeFile["checksum"] = $checksum; + $activeFile["user_name"] = ""; + $activeFile["group_name"] = ""; + $activeFile["file"] = $file_contents; + return true; + } + // Remove a file from the tar archive + function removeFile($filename) { + if($this->numFiles > 0) { + foreach($this->files as $key => $information) { + if($information["name"] == $filename) { + $this->numFiles--; + unset($this->files[$key]); + return true; + } + } + } + return false; + } + // Remove a directory from the tar archive + function removeDirectory($dirname) { + if($this->numDirectories > 0) { + foreach($this->directories as $key => $information) { + if($information["name"] == $dirname) { + $this->numDirectories--; + unset($this->directories[$key]); + return true; + } + } + } + return false; + } + // Write the currently loaded tar archive to disk + function saveTar() { + if(!$this->filename) + return false; + // Write tar to current file using specified gzip compression + $this->toTar($this->filename,$this->isGzipped); + return true; + } + // Saves tar archive to a different file than the current file + function toTar($filename,$useGzip) { + if(!$filename) + return false; + // Encode processed files into TAR file format + $this->__generateTar(); + // GZ Compress the data if we need to + if($useGzip) { + // Make sure we have gzip support + if(!function_exists("gzencode")) + return false; + $file = gzencode($this->tar_file); + } else { + $file = $this->tar_file; + } + // Write the TAR file + $fp = fopen($filename,"wb"); + fwrite($fp,$file); + fclose($fp); + return true; + } +} +?> diff --git a/includes/zip_lib.php b/includes/zip_lib.php new file mode 100755 index 0000000..a12de78 --- /dev/null +++ b/includes/zip_lib.php @@ -0,0 +1,805 @@ +<?php +/** + * GZIP stuff. + * + * Note that we use gzopen()/gzwrite() instead of gzcompress() even if + * gzcompress() is available. Gzcompress() puts out data with + * different headers --- in particular it includes an "adler-32" + * checksum rather than a "CRC32" checksum. Since we need the CRC-32 + * checksum, and since not all PHP's have gzcompress(), we'll just + * stick with gzopen(). + */ +function gzip_cleanup() { + global $gzip_tmpfile; + if ($gzip_tmpfile) + @unlink ($gzip_tmpfile); +} +function gzip_tempnam() { + global $gzip_tmpfile; + if (!$gzip_tmpfile) { + //FIXME: does this work on non-unix machines? + $gzip_tmpfile = tempnam("/tmp", "wkzip"); + register_shutdown_function ("gzip_cleanup"); + } + return $gzip_tmpfile; +} +function gzip_compress($data) { + $filename = gzip_tempnam(); + if (!($fp = gzopen($filename, "wb"))) + trigger_error(sprintf("%s failed", "gzopen"), E_USER_ERROR); + gzwrite($fp, $data, strlen($data)); + if (!gzclose($fp)) + trigger_error(sprintf("%s failed", "gzclose"), E_USER_ERROR); + $size = filesize($filename); + if (!($fp = fopen($filename, "rb"))) + trigger_error(sprintf("%s failed", "fopen"), E_USER_ERROR); + if (!($z = fread($fp, $size)) || strlen($z) != $size) + trigger_error(sprintf("%s failed", "fread"), E_USER_ERROR); + if (!fclose($fp)) + trigger_error(sprintf("%s failed", "fclose"), E_USER_ERROR); + unlink ($filename); + return $z; +} +function gzip_uncompress($data) { + $filename = gzip_tempnam(); + if (!($fp = fopen($filename, "wb"))) + trigger_error(sprintf("%s failed", "fopen"), E_USER_ERROR); + fwrite($fp, $data, strlen($data)); + if (!fclose($fp)) + trigger_error(sprintf("%s failed", "fclose"), E_USER_ERROR); + if (!($fp = gzopen($filename, "rb"))) + trigger_error(sprintf("%s failed", "gzopen"), E_USER_ERROR); + $unz = ""; + while ($buf = gzread($fp, 4096)) + $unz .= $buf; + if (!gzclose($fp)) + trigger_error(sprintf("%s failed", "gzclose"), E_USER_ERROR); + unlink ($filename); + return $unz; +} +/** + * CRC32 computation. Hacked from Info-zip's zip-2.3 source code. + */ +function zip_crc32($str, $crc = 0) { + static $zip_crc_table; + if (empty($zip_crc_table)) { + /* NOTE: The range of PHP ints seems to be -0x80000000 to 0x7fffffff. + * So, had to munge these constants. + */ + $zip_crc_table = [ + 0x00000000, + 0x77073096, + -0x11f19ed4, + -0x66f6ae46, + 0x076dc419, + 0x706af48f, + -0x169c5acb, + -0x619b6a5d, + 0x0edb8832, + 0x79dcb8a4, + -0x1f2a16e2, + -0x682d2678, + 0x09b64c2b, + 0x7eb17cbd, + -0x1847d2f9, + -0x6f40e26f, + 0x1db71064, + 0x6ab020f2, + -0x0c468eb8, + -0x7b41be22, + 0x1adad47d, + 0x6ddde4eb, + -0x0b2b4aaf, + -0x7c2c7a39, + 0x136c9856, + 0x646ba8c0, + -0x029d0686, + -0x759a3614, + 0x14015c4f, + 0x63066cd9, + -0x05f0c29d, + -0x72f7f20b, + 0x3b6e20c8, + 0x4c69105e, + -0x2a9fbe1c, + -0x5d988e8e, + 0x3c03e4d1, + 0x4b04d447, + -0x2df27a03, + -0x5af54a95, + 0x35b5a8fa, + 0x42b2986c, + -0x2444362a, + -0x534306c0, + 0x32d86ce3, + 0x45df5c75, + -0x2329f231, + -0x542ec2a7, + 0x26d930ac, + 0x51de003a, + -0x3728ae80, + -0x402f9eea, + 0x21b4f4b5, + 0x56b3c423, + -0x30456a67, + -0x47425af1, + 0x2802b89e, + 0x5f058808, + -0x39f3264e, + -0x4ef416dc, + 0x2f6f7c87, + 0x58684c11, + -0x3e9ee255, + -0x4999d2c3, + 0x76dc4190, + 0x01db7106, + -0x672ddf44, + -0x102aefd6, + 0x71b18589, + 0x06b6b51f, + -0x60401b5b, + -0x17472bcd, + 0x7807c9a2, + 0x0f00f934, + -0x69f65772, + -0x1ef167e8, + 0x7f6a0dbb, + 0x086d3d2d, + -0x6e9b9369, + -0x199ca3ff, + 0x6b6b51f4, + 0x1c6c6162, + -0x7a9acf28, + -0x0d9dffb2, + 0x6c0695ed, + 0x1b01a57b, + -0x7df70b3f, + -0x0af03ba9, + 0x65b0d9c6, + 0x12b7e950, + -0x74414716, + -0x03467784, + 0x62dd1ddf, + 0x15da2d49, + -0x732c830d, + -0x042bb39b, + 0x4db26158, + 0x3ab551ce, + -0x5c43ff8c, + -0x2b44cf1e, + 0x4adfa541, + 0x3dd895d7, + -0x5b2e3b93, + -0x2c290b05, + 0x4369e96a, + 0x346ed9fc, + -0x529877ba, + -0x259f4730, + 0x44042d73, + 0x33031de5, + -0x55f5b3a1, + -0x22f28337, + 0x5005713c, + 0x270241aa, + -0x41f4eff0, + -0x36f3df7a, + 0x5768b525, + 0x206f85b3, + -0x46992bf7, + -0x319e1b61, + 0x5edef90e, + 0x29d9c998, + -0x4f2f67de, + -0x3828574c, + 0x59b33d17, + 0x2eb40d81, + -0x4842a3c5, + -0x3f459353, + -0x12477ce0, + -0x65404c4a, + 0x03b6e20c, + 0x74b1d29a, + -0x152ab8c7, + -0x622d8851, + 0x04db2615, + 0x73dc1683, + -0x1c9cf4ee, + -0x6b9bc47c, + 0x0d6d6a3e, + 0x7a6a5aa8, + -0x1bf130f5, + -0x6cf60063, + 0x0a00ae27, + 0x7d079eb1, + -0x0ff06cbc, + -0x78f75c2e, + 0x1e01f268, + 0x6906c2fe, + -0x089da8a3, + -0x7f9a9835, + 0x196c3671, + 0x6e6b06e7, + -0x012be48a, + -0x762cd420, + 0x10da7a5a, + 0x67dd4acc, + -0x06462091, + -0x71411007, + 0x17b7be43, + 0x60b08ed5, + -0x29295c18, + -0x5e2e6c82, + 0x38d8c2c4, + 0x4fdff252, + -0x2e44980f, + -0x5943a899, + 0x3fb506dd, + 0x48b2364b, + -0x27f2d426, + -0x50f5e4b4, + 0x36034af6, + 0x41047a60, + -0x209f103d, + -0x579820ab, + 0x316e8eef, + 0x4669be79, + -0x349e4c74, + -0x43997ce6, + 0x256fd2a0, + 0x5268e236, + -0x33f3886b, + -0x44f4b8fd, + 0x220216b9, + 0x5505262f, + -0x3a45c442, + -0x4d42f4d8, + 0x2bb45a92, + 0x5cb36a04, + -0x3d280059, + -0x4a2f30cf, + 0x2cd99e8b, + 0x5bdeae1d, + -0x649b3d50, + -0x139c0dda, + 0x756aa39c, + 0x026d930a, + -0x63f6f957, + -0x14f1c9c1, + 0x72076785, + 0x05005713, + -0x6a40b57e, + -0x1d4785ec, + 0x7bb12bae, + 0x0cb61b38, + -0x6d2d7165, + -0x1a2a41f3, + 0x7cdcefb7, + 0x0bdbdf21, + -0x792c2d2c, + -0x0e2b1dbe, + 0x68ddb3f8, + 0x1fda836e, + -0x7e41e933, + -0x0946d9a5, + 0x6fb077e1, + 0x18b74777, + -0x77f7a51a, + -0x00f09590, + 0x66063bca, + 0x11010b5c, + -0x709a6101, + -0x079d5197, + 0x616bffd3, + 0x166ccf45, + -0x5ff51d88, + -0x28f22d12, + 0x4e048354, + 0x3903b3c2, + -0x5898d99f, + -0x2f9fe909, + 0x4969474d, + 0x3e6e77db, + -0x512e95b6, + -0x2629a524, + 0x40df0b66, + 0x37d83bf0, + -0x564351ad, + -0x2144613b, + 0x47b2cf7f, + 0x30b5ffe9, + -0x42420de4, + -0x35453d76, + 0x53b39330, + 0x24b4a3a6, + -0x452fc9fb, + -0x3228f96d, + 0x54de5729, + 0x23d967bf, + -0x4c9985d2, + -0x3b9eb548, + 0x5d681b02, + 0x2a6f2b94, + -0x4bf441c9, + -0x3cf3715f, + 0x5a05df1b, + 0x2d02ef8d, + ]; + } + $crc = ~$crc; + for ($i = 0; $i < strlen($str); $i++) { + $crc = ($zip_crc_table[($crc ^ ord($str[$i])) & 0xff] ^ (($crc >> 8) & 0xffffff)); + } + return ~$crc; +} +define("GZIP_MAGIC", "\037\213"); +define("GZIP_DEFLATE", 010); +function zip_deflate($content) { + // Compress content, and suck information from gzip header. + $z = gzip_compress($content); + // Suck OS type byte from gzip header. FIXME: this smells bad. + extract (unpack("a2magic/Ccomp_type/Cflags/@9/Cos_type", $z)); + if ($magic != GZIP_MAGIC) + trigger_error(sprintf("Bad %s", "gzip magic"), E_USER_ERROR); + if ($comp_type != GZIP_DEFLATE) + trigger_error(sprintf("Bad %s", "gzip comp type"), E_USER_ERROR); + if (($flags & 0x3e) != 0) + trigger_error(sprintf("Bad %s", sprintf("flags (0x%02x)", $flags)), E_USER_ERROR); + $gz_header_len = 10; + $gz_data_len = strlen($z) - $gz_header_len - 8; + if ($gz_data_len < 0) + trigger_error("not enough gzip output?", E_USER_ERROR); + extract (unpack("Vcrc32", substr($z, $gz_header_len + $gz_data_len))); + return [ + substr($z, $gz_header_len, $gz_data_len), // gzipped data + $crc32, // crc + $os_type, // OS type + ]; +} +function zip_inflate($data, $crc32, $uncomp_size) { + if (!function_exists("gzopen")) { + global $request; + $request->finish(_("Can't inflate data: zlib support not enabled in this PHP")); + } + // Reconstruct gzip header and ungzip the data. + $mtime = time(); //(Bogus mtime) + return gzip_uncompress(pack("a2CxV@10", GZIP_MAGIC, GZIP_DEFLATE, $mtime). $data . pack("VV", $crc32, $uncomp_size)); +} +function unixtime2dostime($unix_time) { + if ($unix_time % 1) + $unix_time++; // Round up to even seconds. + list($year, $month, $mday, $hour, $min, $sec) = explode(" ", date("Y n j G i s", $unix_time)); + if ($year < 1980) + list($year, $month, $mday, $hour, $min, $sec) = [ + 1980, + 1, + 1, + 0, + 0, + 0, + ]; + $dosdate = (($year - 1980) << 9) | ($month << 5) | $mday; + $dostime = ($hour << 11) | ($min << 5) | ($sec >> 1); + return [ + $dosdate, + $dostime, + ]; +} +function dostime2unixtime($dosdate, $dostime) { + $mday = $dosdate & 0x1f; + $month = ($dosdate >> 5) & 0x0f; + $year = 1980 + (($dosdate >> 9) & 0x7f); + $sec = ($dostime & 0x1f) * 2; + $min = ($dostime >> 5) & 0x3f; + $hour = ($dostime >> 11) & 0x1f; + return mktime($hour, $min, $sec, $month, $mday, $year); +} +/** + * Class for zipfile creation. + */ +define("ZIP_DEFLATE", GZIP_DEFLATE); +define("ZIP_STORE", 0); +define("ZIP_CENTHEAD_MAGIC", "PK\001\002"); +define("ZIP_LOCHEAD_MAGIC", "PK\003\004"); +define("ZIP_ENDDIR_MAGIC", "PK\005\006"); +class ZipWriter { + function ZipWriter($comment = "", $zipname = "archive.zip") { + $this->comment = $comment; + $this->nfiles = 0; + $this->dir = ""; // "Central directory block" + $this->offset = 0; // Current file position. + $zipname = addslashes($zipname); + header ("Content-Type: application/zip; name=\"$zipname\""); + header ("Content-Disposition: attachment; filename=\"$zipname\""); + //header( "Content-Disposition: inline; filename=$zipname" ); + } + function addRegularFile($filename, $content, $attrib = false) { + if (!$attrib) + $attrib = []; + $size = strlen($content); + if (function_exists("gzopen")) { + list($data, $crc32, $os_type) = zip_deflate($content); + if (strlen($data) < $size) { + $content = $data; // Use compressed data. + $comp_type = ZIP_DEFLATE; + } else + unset ($crc32); // force plain store. + } + if (!isset($crc32)) { + $comp_type = ZIP_STORE; + $crc32 = zip_crc32($content); + } + if (!empty($attrib["write_protected"])) + $atx = (0100444 << 16) | 1; // S_IFREG + read permissions to + // everybody. + else + $atx = (0100644 << 16); // Add owner write perms. + $ati = $attrib["is_ascii"] ? 1 : 0; + if (empty($attrib["mtime"])) + $attrib["mtime"] = time(); + list($mod_date, $mod_time) = unixtime2dostime($attrib["mtime"]); + // Construct parts common to "Local file header" and "Central + // directory file header." + if (!isset($attrib["extra_field"])) + $attrib["extra_field"] = ""; + if (!isset($attrib["file_comment"])) + $attrib["file_comment"] = ""; + $head = pack("vvvvvVVVvv", 20, // Version needed to extract (FIXME: is this right?) + 0, // Gen purp bit flag + $comp_type, $mod_time, $mod_date, $crc32, strlen($content), $size, strlen($filename), strlen($attrib["extra_field"]), ); + // Construct the "Local file header" + $lheader = ZIP_LOCHEAD_MAGIC . $head . $filename . $attrib["extra_field"]; + // Construct the "central directory file header" + $this->dir .= pack("a4CC", ZIP_CENTHEAD_MAGIC, 23, // Version made by (FIXME: is this right?) + $os_type, ); + $this->dir .= $head; + $this->dir .= pack("vvvVV", strlen($attrib["file_comment"]), 0, // Disk number start + $ati, // Internal file attributes + $atx, // External file attributes + $this->offset, ); // Relative offset of local header + $this->dir .= $filename . $attrib["extra_field"] . $attrib["file_comment"]; + // Output the "Local file header" and file contents. + echo $lheader; + echo $content; + $this->offset += strlen($lheader) + strlen($content); + $this->nfiles++; + } + function finish() { + // Output the central directory + echo $this->dir; + // Construct the "End of central directory record" + echo ZIP_ENDDIR_MAGIC; + echo pack("vvvvVVv", 0, // Number of this disk. + 0, // Number of disk with start of c dir + $this->nfiles, // Number entries on this disk + $this->nfiles, // Number entries + strlen($this->dir), // Size of central directory + $this->offset, // Offset of central directory + strlen($this->comment), ); + echo $this->comment; + } +} +/** + * Class for reading zip files. + * + * BUGS: + * + * Many of the ExitWiki()'s should probably be warn()'s (eg. CRC mismatch). + * + * Only a subset of zip formats is recognized. (I think that + * unsupported formats will be recognized as such rather than silently + * munged.) + * + * We don't read the central directory. This means we don't see the + * file attributes (text? read-only?), or file comments. + * + * Right now we ignore the file mod date and time, since we don't need it. + */ +class ZipReader { + function ZipReader($zipfile) { + if (!is_string($zipfile)) + $this->fp = $zipfile; // File already open + else if (!($this->fp = fopen($zipfile, "rb"))) + trigger_error(sprintf(_("Can't open zip file '%s' for reading"), $zipfile), E_USER_ERROR); + } + function _read($nbytes) { + $chunk = fread($this->fp, $nbytes); + if (strlen($chunk) != $nbytes) + trigger_error(_("Unexpected EOF in zip file"), E_USER_ERROR); + return $chunk; + } + function done() { + fclose ($this->fp); + return false; + } + function readFile() { + $head = $this->_read(30); + extract (unpack("a4magic/vreq_version/vflags/vcomp_type" . "/vmod_time/vmod_date" . "/Vcrc32/Vcomp_size/Vuncomp_size" . "/vfilename_len/vextrafld_len", $head)); + //FIXME: we should probably check $req_version. + $attrib["mtime"] = dostime2unixtime($mod_date, $mod_time); + if ($magic != ZIP_LOCHEAD_MAGIC) { + if ($magic != ZIP_CENTHEAD_MAGIC) + // FIXME: better message? + ExitWiki (sprintf("Bad header type: %s", $magic)); + return $this->done(); + } + if (($flags & 0x21) != 0) + ExitWiki ("Encryption and/or zip patches not supported."); + if (($flags & 0x08) != 0) + // FIXME: better message? + ExitWiki ("Postponed CRC not yet supported."); + $filename = $this->_read($filename_len); + if ($extrafld_len != 0) + $attrib["extra_field"] = $this->_read($extrafld_len); + $data = $this->_read($comp_size); + if ($comp_type == ZIP_DEFLATE) { + $data = zip_inflate($data, $crc32, $uncomp_size); + } else if ($comp_type == ZIP_STORE) { + $crc = zip_crc32($data); + if ($crc32 != $crc) + ExitWiki (sprintf("CRC mismatch %x != %x", $crc, $crc32)); + } else + ExitWiki (sprintf("Compression method %s unsupported", $comp_method)); + if (strlen($data) != $uncomp_size) + ExitWiki (sprintf("Uncompressed size mismatch %d != %d", strlen($data), $uncomp_size)); + return [ + $filename, + $data, + $attrib, + ]; + } +} +/** + * Routines for Mime mailification of pages. + */ +//FIXME: these should go elsewhere (libmime?). +/** + * Routines for quoted-printable en/decoding. + */ +function QuotedPrintableEncode($string) { + // Quote special characters in line. + $quoted = ""; + while ($string) { + // The complicated regexp is to force quoting of trailing spaces. + preg_match("/^([ !-<>-~]*)(?:([!-<>-~]$)|(.))/s", $string, $match); + $quoted .= $match[1] . $match[2]; + if (!empty($match[3])) + $quoted .= sprintf("=%02X", ord($match[3])); + $string = substr($string, strlen($match[0])); + } + // Split line. + // This splits the line (preferably after white-space) into lines + // which are no longer than 76 chars (after adding trailing '=' for + // soft line break, but before adding \r\n.) + return preg_replace('/(?=.{77})(.{10,74}[ \t]|.{71,73}[^=][^=])/s', "\\1=\r\n", $quoted); +} +function QuotedPrintableDecode($string) { + // Eliminate soft line-breaks. + $string = preg_replace('/=[ \t\r]*\n/', "", $string); + return quoted_printable_decode($string); +} +define("MIME_TOKEN_REGEXP", "[-!#-'*+.0-9A-Z^-~]+"); +function MimeContentTypeHeader($type, $subtype, $params) { + $header = "Content-Type: $type/$subtype"; + reset ($params); + while (list($key, $val) = each($params)) { + //FIXME: what about non-ascii printables in $val? + if (!preg_match("/^" . MIME_TOKEN_REGEXP . "$/", $val)) + $val = '"' . addslashes($val). '"'; + $header .= ";\r\n $key=$val"; + } + return "$header\r\n"; +} +function MimeMultipart($parts) { + global $mime_multipart_count; + // The string "=_" can not occur in quoted-printable encoded data. + $boundary = "=_multipart_boundary_" . ++$mime_multipart_count; + $head = MimeContentTypeHeader("multipart", "mixed", ["boundary" => $boundary]); + $sep = "\r\n--$boundary\r\n"; + return $head . $sep . implode($sep, $parts). "\r\n--${boundary}--\r\n"; +} +/** + * For reference see: + * http://www.nacs.uci.edu/indiv/ehood/MIME/2045/rfc2045.html + * http://www.faqs.org/rfcs/rfc2045.html + * (RFC 1521 has been superceeded by RFC 2045 & others). + * + * Also see http://www.faqs.org/rfcs/rfc2822.html + * + * + * Notes on content-transfer-encoding. + * + * "7bit" means short lines of US-ASCII. + * "8bit" means short lines of octets with (possibly) the high-order bit set. + * "binary" means lines are not necessarily short enough for SMTP + * transport, and non-ASCII characters may be present. + * + * Only "7bit", "quoted-printable", and "base64" are universally safe + * for transport via e-mail. (Though many MTAs can/will be configured to + * automatically convert encodings to a safe type if they receive + * mail encoded in '8bit' and/or 'binary' encodings. + */ +function MimeifyPageRevision($page) { + //$page = $revision->getPage(); + // FIXME: add 'hits' to $params + $params = [ + "title" => $page["title"], + "flags" => "", + "author" => !empty( $page["creator_user"] ) ? $page["creator_user"] : NULL, + "version" => $page["version"], + "lastmodified" => $page["last_modified"], + ]; + $params["author_id"] = $page["ip"]; + $params["summary"] = $page["comment"]; + if (isset($page["hits"])) + $params["hits"] = $page["hits"]; + $params["description"] = $page["description"]; + $params["charset"] = "iso-8859-1"; + // Non-US-ASCII is not allowed in Mime headers (at least not without + // special handling) --- so we urlencode all parameter values. + foreach ($params as $key => $val) + $params[$key] = rawurlencode($val); + $out = MimeContentTypeHeader("application", "x-tikiwiki", $params); + $out .= sprintf("Content-Transfer-Encoding: %s\r\n", "binary"); + $out .= "\r\n"; + $lines = split("\n", $page["data"]); + foreach ($lines as $line) { + // This is a dirty hack to allow saving binary text files. See above. + $line = rtrim($line); + $out .= "$line\r\n"; + } + return $out; +} +/** + * Routines for parsing Mime-ified phpwiki pages. + */ +function ParseRFC822Headers(&$string) { + if (preg_match("/^From (.*)\r?\n/", $string, $match)) { + $headers["from "] = preg_replace('/^\s+|\s+$/', "", $match[1]); + $string = substr($string, strlen($match[0])); + } + while (preg_match('/^([!-9;-~]+) [ \t]* : [ \t]* ' . '( .* \r?\n (?: [ \t] .* \r?\n)* )/x', $string, $match)) { + $headers[strtolower($match[1])] = preg_replace('/^\s+|\s+$/', "", $match[2]); + $string = substr($string, strlen($match[0])); + } + if (empty($headers)) + return false; + if (!preg_match("/^\r?\n/", $string, $match)) { + // No blank line after headers. + return false; + } + $string = substr($string, strlen($match[0])); + return $headers; +} +function ParseMimeContentType($string) { + // FIXME: Remove (RFC822 style comments). + // Get type/subtype + if (!preg_match(':^\s*(' . MIME_TOKEN_REGEXP . ')\s*' . "/" . '\s*(' . MIME_TOKEN_REGEXP . ')\s*:x', $string, $match)) + ExitWiki (sprintf("Bad %s", "MIME content-type")); + $type = strtolower($match[1]); + $subtype = strtolower($match[2]); + $string = substr($string, strlen($match[0])); + $param = []; + while (preg_match('/^;\s*(' . MIME_TOKEN_REGEXP . ')\s*=\s*' . "(?:(" . MIME_TOKEN_REGEXP . ')|"((?:[^"\\\\]|\\.)*)") \s*/sx', $string, $match)) { + //" <--kludge for brain-dead syntax coloring + if (strlen($match[2])) + $val = $match[2]; + else + $val = preg_replace('/[\\\\](.)/s', '\\1', $match[3]); + $param[strtolower($match[1])] = $val; + $string = substr($string, strlen($match[0])); + } + return [ + $type, + $subtype, + $param, + ]; +} +function ParseMimeMultipart($data, $boundary) { + if (!$boundary) + ExitWiki ("No boundary?"); + $boundary = preg_quote($boundary); + while (preg_match("/^(|.*?\n)--$boundary((?:--)?)[^\n]*\n/s", $data, $match)) { + $data = substr($data, strlen($match[0])); + if (!isset($parts)) + $parts = []; // First time through: discard leading chaff + else { + if ($content = ParseMimeifiedPages($match[1])) + for (reset($content); $p = current($content); next($content)) + $parts[] = $p; + } + if ($match[2]) + return $parts; // End boundary found. + } + ExitWiki ("No end boundary?"); +} +function GenerateFootnotesFromRefs($params) { + $footnotes = []; + reset ($params); + while (list($p, $reference) = each($params)) { + if (preg_match("/^ref([1-9][0-9]*)$/", $p, $m)) + $footnotes[$m[1]] = sprintf(_("[%d] See [%s]"), $m[1], rawurldecode($reference)); + } + if (sizeof($footnotes) > 0) { + ksort ($footnotes); + return "-----\n" . "!" . _("References"). "\n" . join("\n%%%\n", $footnotes). "\n"; + } + return ""; +} +// Convert references in meta-data to footnotes. +// Only zip archives generated by phpwiki 1.2.x or earlier should have +// references. +function ParseMimeifiedPages($data) { + if (!($headers = ParseRFC822Headers($data)) || empty($headers["content-type"])) { + //trigger_error( sprintf(_("Can't find %s"),'content-type header'), + // E_USER_WARNING ); + return false; + } + $typeheader = $headers["content-type"]; + if (!(list($type, $subtype, $params) = ParseMimeContentType($typeheader))) { + trigger_error(sprintf("Can't parse %s: (%s)", "content-type", $typeheader), E_USER_WARNING); + return false; + } + if ("$type/$subtype" == "multipart/mixed") { + return ParseMimeMultipart($data, $params["boundary"]); + } else if ("$type/$subtype" != "application/x-phpwiki") { + trigger_error(sprintf("Bad %s", "content-type: $type/$subtype"), E_USER_WARNING); + return false; + } + // FIXME: more sanity checking? + $page = []; + $pagedata = []; + $versiondata = []; + foreach ($params as $key => $value) { + if (empty($value)) + continue; + $value = rawurldecode($value); + switch ($key) { + case "pagename": + case "version": + $page[$key] = $value; + break; + case "flags": + if (preg_match("/PAGE_LOCKED/", $value)) + $pagedata["locked"] = "yes"; + break; + case "created": + case "hits": + $pagedata[$key] = $value; + break; + case "lastmodified": + $versiondata["mtime"] = $value; + break; + case "author": + case "author_id": + case "summary": + case "markup": + $versiondata[$key] = $value; + break; + } + } + // FIXME: do we need to try harder to find a pagename if we + // haven't got one yet? + if (!isset($versiondata["author"])) { + global $request; + $user = $request->getUser(); + $versiondata["author"] = $user->getId(); //FIXME:? + } + $encoding = strtolower($headers["content-transfer-encoding"]); + if ($encoding == "quoted-printable") + $data = QuotedPrintableDecode($data); + else if ($encoding && $encoding != "binary") + ExitWiki (sprintf("Unknown %s", "encoding type: $encoding")); + $data .= GenerateFootnotesFromRefs($params); + $page["content"] = preg_replace('/[ \t\r]*\n/', "\n", chop($data)); + $page["pagedata"] = $pagedata; + $page["versiondata"] = $versiondata; + return [$page]; +} +// Local Variables: +// mode: php +// tab-width: 8 +// c-basic-offset: 4 +// c-hanging-comment-ender-p: nil +// indent-tabs-mode: nil +// End: +?> |
