pan100 Skrevet 7. april 2009 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(); ?> Lenke til kommentar
pan100 Skrevet 7. april 2009 Forfatter 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. Lenke til kommentar
[kami] Skrevet 8. april 2009 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] Lenke til kommentar
pan100 Skrevet 8. april 2009 Forfatter 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) Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå