WikiParser.class.php

gehe zur Dokumentation dieser Datei
00001 <?php
00002 
00013 class WikiParser
00014 {
00015      var $linkedObjectIds = array();
00016      
00024      function parse( $text )
00025      {
00026 //        set_time_limit(1);
00027           $zeilen = array();
00028           $nr     = 0;
00029           
00030           foreach( $text as $t )
00031           {
00032 //             $t = $this->fixLinks( $t );  // Verweise vervollstaendigen.
00033                $zeilen[++$nr] = new Line( rtrim($t) );
00034           }
00035 
00036           // $zeilen enthält eine Liste von Zeilenobjekten.
00037           // Der Index ist die Zeilennr. und beginnt bei 1.
00038 //        Html::debug($zeilen,"Zeilen");
00039           
00040           return $this->parseMultiLineText( $zeilen );
00041      }
00042 
00043 
00044 
00051      function parseMultiLineText( $zeilen )
00052      {
00053           global $conf;
00054           
00055           $children     = array();           // Initiales Anlegen der Unterobjektliste.
00056           $anzahlZeilen = count( $zeilen );  // Anzahl Zeilen
00057           
00058           // Erzwingt am Anfang und Ende eine leere Zeile, damit
00059           // nächste und vorige Zeile in der folgenden Schleife immer gefüllt ist.
00060           $zeilen[0]               = new Line('');
00061           $zeilen[$anzahlZeilen+1] = new Line(''); 
00062           
00063           for  ( $zeileNr=1; $zeileNr<=$anzahlZeilen; $zeileNr++ )
00064           {
00065 
00066                $letzteZeile   = $zeilen[$zeileNr-1];
00067                $dieseZeile    = $zeilen[$zeileNr  ];
00068                $naechsteZeile = $zeilen[$zeileNr+1];
00069 
00070 //             Html::debug($dieseZeile,"Zeile");
00071                
00072                // Leerzeilen ignorieren
00073                if   ( $dieseZeile->isEmpty )
00074                {
00075                     continue;
00076                }
00077                
00078                // Inhaltsverzeichnis
00079                // Text nicht parsen
00080                if   ( $dieseZeile->isTableOfContent )
00081                {
00082                     $children[] = new TableOfContentElement();
00083                     continue;
00084                }
00085 
00086 
00087                // Parser deaktiviert für diese Zeile
00088                // Text nicht parsen
00089                if   ( $dieseZeile->isUnparsed )
00090                {
00091                     $children[] = new TextElement( $dieseZeile->value );
00092                     continue;
00093                }
00094 
00095 
00096                // Ueberschriften Teil 1
00097                // Markierung in der Folgezeile mit "...", "---" oder "==="           
00098                if   ( $naechsteZeile->isHeadlineUnderline )
00099                {
00100                     $headline = new HeadlineElement($naechsteZeile->level);
00101                     $headline->children = $this->parseSimple( $dieseZeile->value);
00102                     $children[] = $headline;
00103                     $zeileNr++;
00104                     continue; // Naechste Zeile
00105                }
00106 
00107 
00108                // Ueberschriften Teil 2
00109                // Markierung mit "+++..." am Zeilenbeginn.            
00110                if   ( $dieseZeile->isHeadline )
00111                {
00112                     $headline = new HeadlineElement($dieseZeile->level);
00113                     $headline->children = $this->parseSimple( $dieseZeile->value);
00114                     $children[] = $headline;
00115                     continue; // Naechste Zeile
00116                }
00117                
00118                // Zitate Teil 1
00119                // Zitat ist in separater Zeile angekündigt            
00120                if   ( $dieseZeile->isQuote )
00121                {
00122                     $bisZeileNr = $zeileNr+1;
00123                     do
00124                     {
00125                          $bisZeileNr++;
00126                     }
00127                     while( !$zeilen[$bisZeileNr]->isQuote && $bisZeileNr<=$anzahlZeilen );
00128                     
00129                     $quote = new QuoteElement();
00130                     $zeilenAuszug = array();
00131                     $nr=0;
00132                     for( $zn=$zeileNr+1;$zn<$bisZeileNr;$zn++)
00133                     {
00134                          $zeilenAuszug[++$nr] = $zeilen[$zn];
00135                     }
00136                     $quote->children = $this->parseMultiLineText($zeilenAuszug);
00137                     $zeileNr = $bisZeileNr+1;
00138                     $children[] = $quote;
00139                     continue;
00140                }
00141                
00142 
00143                
00144                // Zitate Teil 2
00145                // Markierung am Zeilenanfang
00146                if   ( $dieseZeile->isQuotePraefix )
00147                {
00148                     $bisZeileNr = $zeileNr;
00149                     while( $bisZeileNr<=$anzahlZeilen && $zeilen[$bisZeileNr]->isQuotePraefix  )
00150                          $bisZeileNr++;
00151                     $bisZeileNr--;
00152 //                  Html::debug($bisZeileNr,"Bis-Zeile-Nr.");
00153                     $quote = new QuoteElement();
00154                     
00155                     $zeilenAuszug = $this->getListenAuszug( $zeilen,$zeileNr,$bisZeileNr);
00156 //                  Html::debug($zeilenAuszug,"Auszug");
00157 //                  die();
00158                     $quote->children = $this->parseMultiLineText($zeilenAuszug);
00159                     $zeileNr = $bisZeileNr;
00160                     $children[] = $quote;
00161                     continue;
00162                }
00163                
00164 
00165                
00166                // Definitionsliste
00167                // Markierung am Zeilenanfang
00168                if   ( $dieseZeile->isDefinition )
00169                {
00170                     $bisZeileNr = $zeileNr;
00171                     while( $bisZeileNr<=$anzahlZeilen && $zeilen[$bisZeileNr]->isDefinition )
00172                          $bisZeileNr++;
00173                     $bisZeileNr--;
00174 
00175                     $defList = new DefinitionListElement();
00176                     
00177                     $zeilenAuszug = $this->getListenAuszug( $zeilen,$zeileNr,$bisZeileNr);
00178 //                  Html::debug($zeilenAuszug,"Auszug");
00179 //                  die();
00180                     foreach( $zeilenAuszug as $zeile )
00181                     {
00182                          $sep = $conf['editor']['text-markup']['definition-sep'];
00183                          list($defKey, $defValue) = explode($sep, $zeile->value);
00184                          
00185                          $defEntry = new DefinitionItemElement();
00186                          $defEntry->key       = $defKey;
00187                          $defEntry->children  = $this->parseSimple($defValue);
00188                          $defList->children[] = $defEntry;
00189                     }
00190                     $zeileNr = $bisZeileNr;
00191                     $children[] = $defList;
00192                     continue;
00193                }
00194                
00195 
00196                
00197                // Code
00198                if   ( $dieseZeile->isCode)
00199                {
00200                     $bisZeileNr = $zeileNr+1;
00201                     while( $bisZeileNr<$anzahlZeilen && !$zeilen[$bisZeileNr]->isCode  )
00202                          $bisZeileNr++;
00203                     
00204                     $code = new CodeElement();
00205                     $code->language = trim($dieseZeile->value);
00206                     
00207                     for( $zn=$zeileNr+1;$zn<$bisZeileNr;$zn++)
00208                     {
00209                          $code->children[] = new TextElement( $zeilen[$zn]->source );
00210                          
00211                          if   ( $zn < $bisZeileNr-1 )
00212                               $code->children[] = new LineBreakElement();
00213                     }
00214                     $zeileNr = $bisZeileNr;
00215                     $children[] = $code;
00216                     continue;
00217                }
00218 
00219 
00220                // Tabellen
00221                if   ( $dieseZeile->isTable )
00222                {
00223                     $bisZeileNr = $zeileNr;
00224                     while( $bisZeileNr<=$anzahlZeilen && $zeilen[$bisZeileNr]->isTable )
00225                          $bisZeileNr++;
00226                     
00227                     $tabelle = new TableElement();
00228                     $zeilenAuszug = array();
00229                     for( $zn=$zeileNr;$zn<=$bisZeileNr;$zn++)
00230                     {
00231                          $zeilenAuszug[$zn-$zeileNr+1] = $zeilen[$zn];
00232                     }
00233                     $tabelle->children = $this->parseTable($zeilenAuszug);
00234                     $children[] = $tabelle;
00235                     $zeileNr = $bisZeileNr+1;
00236                     continue;
00237                }
00238 
00239 
00240                // Listen
00241                if   ( $dieseZeile->isList || $dieseZeile->isNumberedList )
00242                {
00243                     
00244                     $bisZeileNr = $zeileNr;
00245                     while( $bisZeileNr<=$anzahlZeilen &&
00246                            ($zeilen[$bisZeileNr]->isList || $zeilen[$bisZeileNr]->isNumberedList) )
00247                          $bisZeileNr++;
00248                     $bisZeileNr--;
00249 
00250                     if   ( $dieseZeile->isList )
00251                          $liste = new ListElement();
00252                     else
00253                          $liste = new NumberedListElement();
00254                          
00255                     $zeilenAuszug = array();
00256                     $nr=0;
00257 
00258                     for( $zn=$zeileNr;$zn<=$bisZeileNr;$zn++)
00259                     {
00260                          $zeilenAuszug[++$nr] = $zeilen[$zn];
00261                     }
00262 
00263                     $liste->children = $this->parseList($zeilenAuszug,1);
00264                     $children[] = $liste;
00265                     $zeileNr = $bisZeileNr;
00266                     continue;
00267                }
00268 
00269 
00270 
00271                if   ( $dieseZeile->isNormal )
00272                {
00273 //                  Html::debug($dieseZeile,"normale Zeile");
00274                     // Textabsaetze
00275                     $bisZeileNr = $zeileNr;
00276                     while( $bisZeileNr <= $anzahlZeilen      &&
00277                            $zeilen[$bisZeileNr  ]->isNormal     )
00278                     {
00279                          $bisZeileNr++;
00280                     }
00281                     $bisZeileNr--;
00282 //                  Html::debug($zeileNr,"Zeile");
00283 //                  Html::debug($bisZeileNr,"bisZeile-P");
00284 //                  die();    
00285                     
00286                     $para = new ParagraphElement();
00287                     for( $zn=$zeileNr;$zn<=$bisZeileNr;$zn++)
00288                     {
00289                          if   ( !$zeilen[$zn]->isNormal )
00290                               continue;
00291      
00292                          if   ( $zeilen[$zn]->isUnparsed )
00293                               $para->children[] = new TextElement( $zeilen[$zn]->source );
00294                               
00295                          foreach( $this->parseSimple($zeilen[$zn]->value) as $e )
00296                               $para->children[] = $e;
00297                          
00298                          if   ( $zn < $bisZeileNr )
00299                               $para->children[] = new LineBreakElement();
00300                     }
00301                     
00302                     $zeileNr = $bisZeileNr;
00303                     $children[] = $para;
00304                     
00305                     continue;
00306                }
00307                
00308                Html::debug($dieseZeile,"Unbekannte Zeile");
00309                die( 'unknown line: '.$dieseZeile );
00310           }
00311           
00312           return $children;
00313      }
00314 
00315 
00316 
00317      function getListenAuszug( $liste, $von, $bis )
00318      {
00319           $auszug = array();
00320           $idx    = 0;
00321           
00322           for( $j=$von;$j<=$bis;$j++)
00323           {
00324                $auszug[++$idx] = new Line($liste[$j]->value);
00325           }
00326           
00327           return $auszug;
00328      }
00329      
00330      
00334      function parseList( $zeilen,$tiefe )
00335      {
00336           $children = array();
00337           $anzahlZeilen = count( $zeilen );
00338           $entry    = null;
00339           for  ( $zeileNr=1; $zeileNr<=$anzahlZeilen; $zeileNr++ )
00340           {
00341                $dieseZeile = $zeilen[$zeileNr];
00342 
00343                // Listen
00344                if   ( $dieseZeile->indent <= $tiefe )
00345                {
00346                     if   ( $zeileNr > 1 )
00347                          $children[] = $entry;
00348                          
00349                     $entry = new ListEntryElement();
00350                     $entry->children = $this->parseSimple( $dieseZeile->value );
00351                }
00352                else
00353                {
00354                     // Weitere Schachtelung der Liste
00355                     if   ( $dieseZeile->isList )
00356                          $liste = new ListElement();
00357                     else
00358                          $liste = new NumberedListElement();                    
00359 
00360                     $bisZeileNr = $zeileNr;
00361 
00362                     while( $bisZeileNr<=$anzahlZeilen && $zeilen[$bisZeileNr]->indent != $tiefe )
00363                          $bisZeileNr++;
00364                     $bisZeileNr--;
00365                     
00366 //                  echo "von $zeileNr bis $bisZeileNr (insges. $anzahlZeilen)";
00367                     $zeilenAuszug = array();
00368                     $nr=0;
00369                     for( $zn=$zeileNr;$zn<=$bisZeileNr;$zn++)
00370                     {
00371                          $zeilenAuszug[++$nr] = $zeilen[$zn];
00372                     }
00373                     $liste->children = $this->parseList($zeilenAuszug,$tiefe+1);
00374                     $entry->children[] = $liste;
00375                     $zeileNr = $bisZeileNr;
00376                }
00377           }
00378           $children[] = $entry;
00379           
00380           return $children;
00381      }
00382 
00383 
00387      function parseTable( $zeilen )
00388      {
00389           $children = array();
00390           $anzahlZeilen = count( $zeilen );
00391           for  ( $zeileNr=1; $zeileNr<=$anzahlZeilen; $zeileNr++ )
00392           {
00393                $dieseZeile    = $zeilen[$zeileNr];
00394 
00395                $zeile = new TableLineElement();
00396                
00397                // Listen
00398                $zellen  = explode('|',$dieseZeile->source);
00399                $colSpan = 1;
00400                
00401                foreach( $zellen as $zellenInhalt )
00402                {
00403                     if   ( $zellenInhalt=='')
00404                     {
00405                          $colSpan++;
00406                          continue;
00407                     }
00408                     
00409                     $zelle = new TableCellElement();
00410                     $zelle->colSpan = $colSpan;
00411                     $colSpan = 1;
00412                     
00413                     if   ( substr($zellenInhalt,0,1) == '!' )
00414                     {
00415                          $zelle->isHeading = true;
00416                          $zellenInhalt     = substr($zellenInhalt,1);
00417                     }
00418                     
00419                     $zelle->children = $this->parseSimple( $zellenInhalt);
00420                     
00421                     $zeile->children[] = $zelle;
00422                }
00423                
00424                $children[] = $zeile;
00425           }
00426           
00427           return $children;
00428      }
00429      
00430 
00431 
00432      function parseLinks( $text )
00433      {
00434           $conf = Session::getConfig();
00435           $text_markup = $conf['editor']['text-markup']; 
00436 
00437           $posM = strpos($text,'"'.$text_markup['linkto'].'"');
00438 
00439           if   ( $posM === false )
00440                return false;
00441 
00442           $posL = strpos(substr($text,0,$posM-1),'"');
00443 
00444           if   ( $posL === false )
00445                return false;
00446 
00447           $posR = strpos($text,'"',$posM+4);
00448 
00449           if   ( $posR === false )
00450                return false;
00451 
00452           $parts = array();             
00453           $parts[] = substr($text,0      ,$posL        );  // Anfang
00454           $parts[] = substr($text,$posL+1,$posM-$posL-1);  // Linktext
00455           $parts[] = substr($text,$posM+4,$posR-$posM-4);  // Verweisziel
00456           $parts[] = substr($text,$posR+1              );  // Rest
00457 
00458           return $parts;
00459      }
00460      
00461      
00465      function parseImages( $text )
00466      {
00467           $posM = strpos($text,'image:');
00468 
00469           if   ( $posM === false )
00470                return false;
00471 
00472           $posL = strpos(substr($text,0,$posM-1),'"');
00473 
00474           if   ( $posL === false )
00475                return false;
00476 
00477           $posR = strpos($text,'"',$posM+4);
00478 
00479           if   ( $posR === false )
00480                return false;
00481 
00482           $parts = array();             
00483           $parts[] = substr($text,0      ,$posL        );  // Anfang
00484           $parts[] = substr($text,$posL+1,$posM-$posL-1);  // Linktext
00485           $parts[] = substr($text,$posM+4,$posR-$posM-4);  // Verweisziel
00486           $parts[] = substr($text,$posR+1              );  // Rest
00487           
00488           return $parts;
00489      }
00490      
00491      
00492 
00501      function parseSimpleParts( $text,$sepLinks,$sepRechts )
00502      {
00503           $posL = strpos($text,$sepLinks);
00504 
00505           if   ( $posL === false )
00506                return false;
00507 
00508           $posR = strpos($text,$sepRechts,$posL+strlen($sepLinks));
00509 
00510           if   ( $posR === false )
00511                return false;
00512 
00513           $parts = array();             
00514           $parts[] = substr($text,0      ,$posL        );
00515           $parts[] = substr($text,$posL+strlen($sepLinks),$posR-$posL-strlen($sepLinks));
00516           $parts[] = substr($text,$posR+strlen($sepRechts)                             );
00517 
00518           return $parts;
00519      }
00520      
00521      
00522      
00526      function parseEscapes( $text )
00527      {
00528           $posL = strpos($text,'\\');
00529 
00530           if   ( $posL === false )
00531                return false;
00532 
00533           $parts = array();             
00534           $parts[] = substr($text,0         ,$posL );
00535           $parts[] = substr($text,$posL+1,1 );
00536           $parts[] = substr($text,$posL+2   );
00537 
00538           return $parts;
00539      }
00540      
00541      
00542      
00552      function parseSimpleElement( $text,$sepL,$sepR,$className )
00553      {
00554           $erg = $this->parseSimpleParts( $text,$sepL,$sepR );
00555           if   ( is_array($erg) )
00556           {
00557                $idx   = -1;
00558                $elements = array();
00559                
00560                $davor = $this->parseSimple($erg[++$idx]);
00561                foreach( $davor as $davorEl )
00562                     $elements[] = $davorEl;
00563 
00564                $newEl = new $className();
00565                $newEl->children = $this->parseSimple($erg[++$idx]); 
00566                $elements[] = $newEl;
00567 
00568                $danach = $this->parseSimple($erg[++$idx]);
00569                foreach( $danach as $danachEl )
00570                     $elements[] = $danachEl;
00571                return $elements;
00572           }
00573           
00574           return false;
00575      }
00576      
00577      
00578 
00585      function fixLinks( $text )
00586      {
00587           // Text->... umsetzen nach "Text"->... (Anfuehrungszeichen ergaenzen)
00588           $text = ereg_replace( '([A-Za-z0-9._-]+)\->','"\\1"->',$text );
00589      
00590           // ...->Link umsetzen nach ...->"Link" (Anfuehrungszeichen ergaenzen)
00591           $text = ereg_replace( '\->([A-Za-z0-9\.\:\_\/\,\?\=\&-]+)','->"\\1"',$text );
00592 
00593           // alleinstehende externe Links
00594           // Funktioniert nicht richtig, erstmal deaktiviert.
00595 //        $text = ereg_replace( '((https?|ftps?|news|gopher):\/\/([A-Za-z0-9._\/\,-]+))([^"])','"\\1"->"\\1"\\2',$text );
00596 
00597           // alleinstehende E-Mail Adressen
00598           $text = ereg_replace( '([A-Za-z0-9._-]+@[A-Za-z0-9\.\_\-]+)([^A-Za-z0-9\.\_\-\"])','"\\1"->"mailto:\\1"\\2',$text );
00599 
00600           // Bilder
00601           $text = ereg_replace( 'ima?ge?:\/?\/?([A-Za-z0-9\.\:\_\/\,\?\=\&-]+)','{\\1}',$text );
00602           
00603           return $text;
00604      }
00605      
00606      
00607      
00614      function parseSimple( $text )
00615      {
00616           $conf = Session::getConfig();
00617           $text_markup = $conf['editor']['text-markup'];
00618           
00619           $text = $this->fixLinks($text);
00620           $elements = array();
00621           
00622           if   ( trim($text) == '' )
00623                return $elements;
00624 
00625           $erg = $this->parseLinks( $text );
00626           if   ( is_array($erg) )
00627           {
00628                $idx   = -1;
00629                
00630                $davor = $this->parseSimple($erg[++$idx]);
00631                foreach( $davor as $davorEl )
00632                     $elements[] = $davorEl;
00633 
00634                $link = new LinkElement();
00635                $link->children = $this->parseSimple($erg[++$idx]); 
00636                $link->setTarget( $erg[++$idx] ); 
00637                
00638                if   ( $link->objectId != 0 )
00639                     $this->linkedObjectIds[] = $link->objectId;
00640                $elements[] = $link;
00641 
00642                $danach = $this->parseSimple($erg[++$idx]);
00643                foreach( $danach as $danachEl )
00644                     $elements[] = $danachEl;
00645 
00646                return $elements;
00647           }
00648 
00649 
00650           $erg = $this->parseSimpleParts( $text,$text_markup['image-begin'],$text_markup['image-end'] );
00651           if   ( is_array($erg) )
00652           {
00653                $idx   = -1;
00654                
00655                $davor = $this->parseSimple($erg[++$idx]);
00656                foreach( $davor as $davorEl )
00657                     $elements[] = $davorEl;
00658 
00659                $image = new ImageElement();
00660                $t = new TextElement($erg[++$idx]);
00661                $image->setTarget( intval($t->text) );
00662                $t->text = '';
00663                $image->children[] = $t;
00664                 
00665                if   ( $image->objectId != 0 )
00666                     $this->linkedObjectIds[] = $image->objectId;
00667                $elements[] = $image;
00668 
00669                $danach = $this->parseSimple($erg[++$idx]);
00670                foreach( $danach as $danachEl )
00671                     $elements[] = $danachEl;
00672 
00673                return $elements;
00674           }
00675 
00676           $erg = $this->parseEscapes( $text );
00677           if   ( is_array($erg) )
00678           {
00679                $idx   = -1;
00680                
00681                $davor = $this->parseSimple($erg[++$idx]);
00682                foreach( $davor as $davorEl )
00683                     $elements[] = $davorEl;
00684 
00685                $t = new TextElement($erg[++$idx]);
00686                $elements[] = $t;
00687 
00688                $danach = $this->parseSimple($erg[++$idx]);
00689                foreach( $danach as $danachEl )
00690                     $elements[] = $danachEl;
00691 
00692                return $elements;
00693           }
00694 
00695           $erg = $this->parseSimpleElement( $text,$text_markup['footnote-begin'],$text_markup['footnote-end'],'FootnoteElement' );
00696           if   ( is_array($erg) )
00697                return $erg;
00698 
00699           $erg = $this->parseSimpleElement( $text,$text_markup['strong-begin'],$text_markup['strong-end'],'StrongElement' );
00700           if   ( is_array($erg) )
00701                return $erg;
00702 
00703           $erg = $this->parseSimpleElement( $text,$text_markup['emphatic-begin'],$text_markup['emphatic-end'],'EmphaticElement' );
00704           if   ( is_array($erg) )
00705                return $erg;
00706 
00707           $erg = $this->parseSimpleElement( $text,$text_markup['code-begin'],$text_markup['code-end'],'TeletypeElement' );
00708           if   ( is_array($erg) )
00709                return $erg;
00710 
00711           $erg = $this->parseSimpleElement( $text,$text_markup['insert-begin'],$text_markup['insert-end'],'InsertedElement' );
00712           if   ( is_array($erg) )
00713                return $erg;
00714 
00715           $erg = $this->parseSimpleElement( $text,$text_markup['remove-begin'],$text_markup['remove-end'],'RemovedElement' );
00716           if   ( is_array($erg) )
00717                return $erg;
00718 
00719           $erg = $this->parseSimpleElement( $text,$text_markup['speech-begin'],$text_markup['speech-end'],'SpeechElement' );
00720           if   ( is_array($erg) )
00721                return $erg;
00722 
00723           
00724           $t = new TextElement($text);
00725           $elements[] = $t;
00726           
00727           return $elements;
00728      }
00729 }
00730 
00731 ?>

Erzeugt am Thu May 14 00:55:49 2009 für OpenRat von  doxygen 1.5.8