Gå til innhold

Fjerne bbCode-tagger


Anbefalte innlegg

Jeg har en database med diverse bbCode-lignende tagger.

Dette må jeg nå konvertere til HTML. De fleste taggene skal jeg klare helt fint å konvertere men den har også en listestruktur jeg sliter litt med.

Strukturen ser slik ut:

 

[li]Punkt 1[/li]

[li]Punkt 2

[li]Underpunkt 1[/li]

[li]Underpunkt 2[/li]

[/li]

[li]Punkt 3[/li]

 

Dette ønsker jeg da skal konverteres til å ha en korrekt struktur med <ul> og <li> (og også <ul> inne i en <li>). Resultatet skal da altså bli slik:

 

<ul>

<li>Punkt 1</li>

<li>Punkt 2

<ul>

<li>Underpunkt 1</li>

<li>Underpunkt 2</li>

</ul>

</li>

<li>Punkt 3</li>

</ul>

 

Er det noen som har noen gode måter å gjøre dette på?

Lenke til kommentar
Videoannonse
Annonse

Utfordringa er at dataene ikke følger bbCode-"standarden" hvor man har en placeholder utenfor lista.
Her på diskusjon.no brukes følgende:

[list]
[*]Punkt 1[/*]
[*]Punkt 1[/*]
[/list] 

Hadde dataene jeg jobber med hatt et slik format ville jeg nok kunne bruke linkene dine, og hadde forsåvidt enkelt kunne rettet opp i det selv. Det har jo ingen

  • i denne databasen så da blir det litt vanskeligere.
Lenke til kommentar

Hva er det som skiller listene? Altså hva ønsker du skal definere at her starter og slutter en liste?

 

Når du kommer til en [li] og du ikke er i en liste generer du <ul><li>.

 

Når du er i en liste forventer du [li] rett etter [/li] Hvis du ikke får [li] genererer du </ul>.

Endret av Emancipate
Lenke til kommentar

Dataene blir som i første post, altså noe lignende dette:

 

Strukturen ser da f.eks. slik ut:

Diverse tekst som ikke hører til punktlista

[li]Punkt 1[/li]

[li]Punkt 2

[li]Underpunkt 1[/li]

[li]Underpunkt 2[/li]

[/li]

[li]Punkt 3[/li]

Diverse annen tekst som ikke hører til punktlista

 

Lenke til kommentar

Det må en ganske komplisert regel til, beskrevet under i pesudo-kode.

MainLoop:
    CurrentText = GetNextTextPiece()
    MainLoopWithoutUpdate:
    if CurrentText = [li] // ** 1
        output "<ul> <li>"
    else if CurrentText = [/li] // ** 2
        output "</li>"
        CurrentText = GetNextTextPiece()
                    while CurrentText = space/newline  // skip optional space/newline
                        output CurrentText
                        CurrentText = GetNextTextPiece()
                    end while // end skip optional space/newline
        if CurrentText = "[li]" // ** 3
            output "<li>"
        else                    // ** 4
            output "</ul>"
            GoTo MainLoopWithoutUpdate
        end if
    else    // ** 5
        output CurrentText
    end if
if CurrentText != "" GoTo MainLoop

GetNextTextPiece() er en funksjon som leser fra input og gir en kort streng. I dette eksempelet bør den dele opp teksten i [li] [/li] mellomrom, ny linje, alle andre tegn. I eksempelet er gyldig utput fra reperterte kall til getnexttextpiece for eksempel slik (hvert resultat på ny linje):

 

Diverse tekst som ikke hører til punktlista

#LF

[li]

Punkt

#SPACE

1

#LF

[/li]

#LF

[li]

P

un

kt

#SPACE

2

#LF

[li]

#LF

Underpunkt

 

osv... Om du virkelig vil gjøre det enkelt returnerer du én og én bokstav (unntatt når du har med en li-tag å gjøre).

Endret av Emancipate
Lenke til kommentar

Hehe, jeg forvirret kanskje mer en jeg hjalp, men det var jo faktisk et kinkig spørsmål.

 

Hvis man sltter linjeskift og mellomrom mellom taggene kan man tilsynelatende gjøre noen replace-operasjoner *i riktig rekkefølge* for å implementere reglene i posten over.

 

Hvis du har String$ = ReplaceString(String$, StringToFind$, ReplacementString$):

 

 

// Hvis [li] kommer rett etter [/li] er det et nytt element i samme liste (og vi avslutter det forrige)
In = ReplaceString(In, "[/li][li]", "</li><li>")
 
// Ellers påbegynnes en ny liste
In = ReplaceString(In, "[li]", "<ul><li>")
 
// Til sist, lukk listen når vi har [/li] uten [li] rett etter
In = ReplaceString(In, "[/li]", "</li></ul>")
 
Lenke til kommentar

Etter en del tenking kom også jeg frem til at dette var litt kinkig :)

 

Jeg fikk lagt inn noe regular expression replace for å fjerne alle whitespace mellom [li] og [/li] taggene, og med en vanlig replace med din rekkefølge ser det ut til at det gjør akkurat det jeg var på jakt etter.

Koden ser da ut som følgende

// Fjerne whitespace
$bm = preg_replace('#\[/li\](.\s?)\[li\]#si', '[/li][li]', $bm);

$text = str_replace("[/li][li]", "</li><li>", $text);
$text = str_replace("[li]", "<ul><li>", $text);
$text = str_replace("[/li]", "</li></ul>", $text);

Dette ser ut til å (foreløpig) fungere utmerket, så får jeg kjøre konverteringen på alt og se om det dukker opp noen spesialtilfeller.

Takk for hjelpen :)

Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...