pan100 Skrevet 7. april 2009 Rapporter Del Skrevet 7. april 2009 Hei folkens. Jeg holder på med å lage et skript som tar en streng som inneholder bb-kode og legger det inn i et DOMDocument-objekt etter en egendefinert XML-syntaks. Det skal senere parses med XSLT over til xhtml, flash eller liknende. Kan dere se på det om det kan forkortes/forbedres på noe måte? <?php $dom = new DOMDocument(); $dom->encoding = 'UTF-8'; $string= "Dette er en [b]streng [i]som er[/i][/b] full av [i]BB-kode[/i], som [size=5]skal parses.[/size]"; $root = $dom->createElement("root"); $dom->appendChild($root); $text = $dom->createElement("text"); $root->appendChild($text); BBtoDOM($string, $text, $dom); /* Begynn på første tegn i strengen. for hvert tegn som ikke er en "[": - Legg til strengen i en midlertidig streng som skal legges til som et textElement under elementet text */ function BBtoDOM($string, $initialElement, $domDocument) { $dom = $domDocument; $textNodeContent = ""; $stringArr = str_split($string); $elementHierarchy = array(); $elementHierarchy[0] = $initialElement; $hierarchyLevel = 0; $tagHierarchy = array(); $tagHierarchy[0] = ""; $posisjon = 0; while($posisjon <= (count($stringArr) -1)) { $tegn = $stringArr[$posisjon]; //hvis tegnet er en start av en kode, så bearbeider vi koden if($tegn == "[") { //hvis ikke textNodeContent er tom, legg det til i elementet som er valgt i hierarkiet if($textNodeContent != "") { $elementHierarchy[$hierarchyLevel]->appendChild($dom->createTextNode($textNodeContent)); $textNodeContent = ""; } //Lag en streng med alle tegn mellom "[" og "]" $bbcodeFound = substr($string, $posisjon); $posOfTagEnd = strcspn($bbcodeFound, "]") + 1; $bbcodeFound = substr($bbcodeFound, 0, $posOfTagEnd); //sjekk om det er starten av en tag eller slutten if(strrpos($bbcodeFound, "/") == 1) { //slutten av en tag //få tak i ordet $tagWord = substr($bbcodeFound, 2); $tagWord = substr($tagWord, 0, strlen($tagWord) -1); //hvis sluttaggen stemmer overens med den aktive taggen på øverste nivå og nivået er større enn 0 if($tagWord == $tagHierarchy[$hierarchyLevel] && $hierarchyLevel > 0) { //legg elementet inn i elementet over $elementHierarchy[$hierarchyLevel-1]->appendChild($elementHierarchy[$hierarchyLevel]); //flytt posisjonen opp til elementet over i hierarkiet $hierarchyLevel--; } //ellers bare ignorer (posisjon flyttes til etter taggen til slutt i sjekken) } else { //begynnelsen av en tag //det før en eventuell = forteller oss hva det er $tagWord = substr($bbcodeFound, 1); //hvis taggen har en verdi ("="tegn) legg den i variabelen $tagValue og sett $tagWord til å være det før //likhetstegnet. if($posOfEqual = strpos($tagWord, "=")) { $tagWord = substr($tagWord, 0, $posOfEqual); $tagValue = substr($bbcodeFound, ($posOfEqual + 2), -1); } //hvis ikke taggen har en verdi sett $tagValue til false. else { $tagWord = substr($tagWord, 0, strlen($tagWord) -1); $tagValue = false; } //hvis taggen er gyldig if(tagIsValid($tagWord)) { if($tagWord == "size") { //size må ha "=" og et tall for fontstørrelse som verdi if(is_numeric($tagValue)) { $newElement = $dom->createElement("bb_size"); $sizeElementAttr = $dom->createAttribute("fontsize"); $sizeElementAttr->value = $tagValue; $newElement->appendChild($sizeElementAttr); $tagHierarchy[$hierarchyLevel+1] = "size"; } } else if($tagWord == "b") { $newElement = $dom->createElement("bb_bold"); $tagHierarchy[$hierarchyLevel+1] = "b"; } else if($tagWord == "i") { $newElement = $dom->createElement("bb_italic"); $tagHierarchy[$hierarchyLevel+1] = "i"; } else if($tagWord == "u") { $newElement = $dom->createElement("bb_underline"); $tagHierarchy[$hierarchyLevel+1] = "u"; } else if($tagWord == "s") { $newElement = $dom->createElement("bb_strikethrough"); $tagHierarchy[$hierarchyLevel+1] = "s"; } else if($tagWord == "center") { $newElement = $dom->createElement("bb_center"); $tagHierarchy[$hierarchyLevel+1] = "center"; } else if($tagWord == "ul") { $newElement = $dom->createElement("bb_unorderedlist"); $tagHierarchy[$hierarchyLevel+1] = "ul"; } else if($tagWord == "ol") { $newElement = $dom->createElement("bb_orderedlist"); $tagHierarchy[$hierarchyLevel+1] = "ol"; } else if($tagWord == "li") { $newElement = $dom->createElement("bb_listelement"); $tagHierarchy[$hierarchyLevel+1] = "li"; } else if($tagWord == "youtube") { $newElement = $dom->createElement("bb_youtube"); $tagHierarchy[$hierarchyLevel+1] = "youtube"; } else if($tagWord == "gvideo") { $newElement = $dom->createElement("bb_googlevid"); $tagHierarchy[$hierarchyLevel+1] = "gvideo"; } else if($tagWord == "color") { //color må ha en verdi etter likhetstegnet, enten stavet farge eller html-kode for farge if($tagValue) { $newElement = $dom->createElement("bb_color"); $sizeElementAttr = $dom->createAttribute("value"); $sizeElementAttr->value = $tagValue; $newElement->appendChild($sizeElementAttr); $tagHierarchy[$hierarchyLevel+1] = "color"; } } else if($tagWord == "quote") { //quote må ikke ha et likhetstegn, men kan ha det, nemlig navnet på den som siteres if($tagValue) { $newElement = $dom->createElement("bb_quote"); $sizeElementAttr = $dom->createAttribute("name"); $sizeElementAttr->value = $tagValue; $newElement->appendChild($sizeElementAttr); $tagHierarchy[$hierarchyLevel+1] = "quote"; } else { $newElement = $dom->createElement("bb_quote"); $tagHierarchy[$hierarchyLevel+1] = "quote"; } } else if($tagWord == "url") { //url har adressen bak et likhetstegn og navnet på linken som innhold eller ingen likhetstegn og //adressen som innhold if($tagValue) { $newElement = $dom->createElement("bb_link"); $sizeElementAttr = $dom->createAttribute("url"); $sizeElementAttr->value = $tagValue; $newElement->appendChild($sizeElementAttr); $tagHierarchy[$hierarchyLevel+1] = "url"; } else { $newElement = $dom->createElement("bb_link"); $tagHierarchy[$hierarchyLevel+1] = "url"; } } else if($tagWord == "img") { //hvis den har likhetstegn, så er det (tall)x(tall) altså størrelsen. Ikke påkrevet. if($tagValue) { $newElement = $dom->createElement("bb_img"); $sizeElementAttr = $dom->createAttribute("size"); $sizeElementAttr->value = $tagValue; $newElement->appendChild($sizeElementAttr); $tagHierarchy[$hierarchyLevel+1] = "img"; } else { $newElement = $dom->createElement("bb_img"); $tagHierarchy[$hierarchyLevel+1] = "img"; } } //legg inn på toppen av hierarkiet if(isset($newElement)) { $elementHierarchy[$hierarchyLevel + 1] = $newElement; unset($newElement); //øk hierarcchyLevel med en $hierarchyLevel ++; } } //ellers ikke gjør noe, bare ignorèr } $posisjon += $posOfTagEnd; } //hvis det ikke er en "[" så er det vanlig innhold. Legg til i tekststrengen til det finnes en tag. else { $textNodeContent .= $tegn; $posisjon++; //har vi nådd slutten av taggen, legg til innhold i nåværende tag og lukk alle tags. if($posisjon == count($stringArr)) { $elementHierarchy[$hierarchyLevel]->appendChild($dom->createTextNode($textNodeContent)); while($hierarchyLevel > 0) { $elementHierarchy[$hierarchyLevel-1]->appendChild($elementHierarchy[$hierarchyLevel]); $hierarchyLevel--; } } } } } /* Give this function a the word inside the [] before eventual "=" sign it returns true if it is in the valid bbcode vocabulary, false if it is unknown. */ function tagIsValid($tagWord) { $validTags = array ("b", "i", "u", "s", "size", "color", "center", "quote", "url", "img", "ul", "ol", "li", "code", "youtube", "gvideo"); if(in_array($tagWord, $validTags)) { return true; } else return false; } $dom->formatOutput=true; echo $dom->saveXML(); ?> Siter Lenke til kommentar
pan100 Skrevet 7. april 2009 Forfatter Rapporter Del Skrevet 7. april 2009 hadde vært veldig gøy hvis noen hadde fått til å forkorte dette litt... Er veldig langt og det er jo sunt å få noen andre til å se på det og komme med kommentarer. Den virker, bare test det ut. Siter Lenke til kommentar
[kami] Skrevet 8. april 2009 Rapporter Del Skrevet 8. april 2009 (endret) alle if og elseifene dine gjør jo stort sett det samme.. tenker på disse else if($tagWord == "b") { $newElement = $dom->createElement("bb_bold"); $tagHierarchy[$hierarchyLevel+1] = "b"; } else if($tagWord == "i") { $newElement = $dom->createElement("bb_italic"); $tagHierarchy[$hierarchyLevel+1] = "i"; } om du hadde satt opp et array på forhånd med translasjonene.. ie $trans = array('i' => 'i', 'youtube' => 'bb_youtube'); // etc. // så kan du bytte ut alle if/elseifene med noe mer generisk kode if( tagIsValid($tagWord) ) { $newElement = $dom->createElement($trans[$tagWord]); $tagHierarchy[$hierarchyLevel+1] = $tagWord; } så kunne du også ha brukt den i denne funksjonen function tagIsValid($tagWord) function tagIsValid($tagWord) { return array_key_exists($tagWord, $trans); } Endret 8. april 2009 av [kami] Siter Lenke til kommentar
pan100 Skrevet 8. april 2009 Forfatter Rapporter Del Skrevet 8. april 2009 alle if og elseifene dine gjør jo stort sett det samme.. tenker på disse else if($tagWord == "b") { $newElement = $dom->createElement("bb_bold"); $tagHierarchy[$hierarchyLevel+1] = "b"; } else if($tagWord == "i") { $newElement = $dom->createElement("bb_italic"); $tagHierarchy[$hierarchyLevel+1] = "i"; } om du hadde satt opp et array på forhånd med translasjonene.. ie $trans = array('i' => 'i', 'youtube' => 'bb_youtube'); // etc. // så kan du bytte ut alle if/elseifene med noe mer generisk kode if( tagIsValid($tagWord) ) { $newElement = $dom->createElement($trans[$tagWord]); $tagHierarchy[$hierarchyLevel+1] = $tagWord; } så kunne du også ha brukt den i denne funksjonen function tagIsValid($tagWord) function tagIsValid($tagWord) { return array_key_exists($tagWord, $trans); } Takker for innspillet! Skal få gjort det på de taggene som ikke kan ha verdier i seg (det vil si et likhetstegn med noe bak) Siter Lenke til kommentar
Anbefalte innlegg
Bli med i samtalen
Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.