[PHP][UBB] Childtag problemen.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 16-09 19:01
Ik ben bezig met het maken van een UBB parser waarvan de tags aanpasbaar zijn. Dit ding werkt tevens niet met regexen oid.
Dus je zou het wel een aardige vorm van Stack Based kunnen noemen :P

Maar goed, het probleem:
Ik heb een functie die de tags moet parsen.
Hij zoekt de eerste tag, stopt alles na de openingstag in een array totdat de sluitingstag wordt gevonden.
Dit gaat allemaal goed, maar bij de sluitingstag wordt gelijk gecheckt of er child tags zijn. Als dat zo is moet de functie zichzelf aanroepen. En daar komt het probleem.
Hij geeft wel de goede waarde mee maar als ik hem zichzelf laat aanroepen dan komt er totaal geen output uit. Het zal vast wel weer een vrij eenvoudige oplossing zijn maar ik zit totaal in de knoop.


Mn code verneukt de layout :/
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?php
/********************************************************************/
/*  Dynasoft UBB Parser                                     */
/*  (c) 2003 J.A. den Hoed                          */
/********************************************************************/

$left_delimiter  = "[";
$right_delimiter = "]";
$end_char        = "/";
$return          = "";

$verbose         = true;

//Tagnaam, HTML-open-tags, HTML-close-tags, valid-childs (,), params
$settings = Array (
                'b'         => Array ('<b>', '</b>', '', 'u|i|s|url', 0),
                'i'         => Array ('<i>', '</i>', '', 'b|u|s|url', 0),
                'u'         => Array ('<u>', '</u>', '', 'i|s|b|url', 0),
                's'         => Array ('<s>', '</s>', '', 'b|u|i|url', 0),
                'url'       => Array ('<a href="', '</a>', '" target="_blank">', '', 1)
                  );
//Deze functie is afgeleid uit de functie van MisterData :-P
function buildStack ($input)
{
    global $left_delimiter, $right_delimiter;
    $source = $input;
    $source = " " . $source;
    $source = str_replace ("][", "] [", $source);
    $iselement = false;
    $tok = strtok ($source, $left_delimiter);
    while (!($tok === FALSE))
    {
        if (!$iselement)
        {
            $tree[] = $tok;
            $iselement = true;
            $tok = strtok ($right_delimiter);
        }
        else
        {
            $tree[] = $left_delimiter . $tok . $right_delimiter;
            $iselement = false;
            $tok = strtok ($left_delimiter);
        }
    }
    return $tree;
}

function parseTree ($input, $childOf = "")
{
    global $left_delimiter, $right_delimiter, $end_char, $return, $settings, $verbose;
    
    //Kijk of de input al een stack is
    if (!is_array ($input))
    {
        $workArray = buildStack ($input);
    }

    //Als de return leeg is, is dit als het goed is de eerste keer dat deze functie aangeroepen wordt.
    //Maar in de child aanroepen moet hij niet een $return gaan toevoegen om ranzige html te voorkomen.
    if (!empty ($return))
    {
        $currOutput = $return;
        $return = "";
    }
    
    //Check of er tags aanwezig zijn    
    if (count ($workArray) > 1)
    {
        foreach ($workArray as $key => $value)
        {
            if (substr ($value, 0, 1) == $left_delimiter 
&& substr ($value, -1) == $right_delimiter 
&& substr ($value, 1, 1) != $end_char 
&& $inTag == false)
            {               
                //We hebben te maken met een openingstag    
                
                //Explode de tag op = om te kijken of er params zijn
                $expArr = explode ("=", $value);
                
                //Kijk of er parameters aangetroffen zijn
                if (count ($expArr) > 1)
                {
                    //Zo ja zet de currentTag en definieer de $param
                    $currentTag = substr ($expArr[0], 1, strlen ($expArr[0]) - 1);
                    $param      = substr ($expArr[1], 0, strlen ($expArr[1]) - 1);
                }
                else
                {
                    //Zo nee definieer de currentTag
                    $currentTag = substr ($value, 1, strlen ($value) - 2);                  
                }
                
                //Stel in dat we in een tag zitten
                $inTag = true;
            }           
            elseif ($value == $left_delimiter . $end_char . $currentTag . $right_delimiter && $inTag == true)
            {
                //We hebben te maken met een closetag
                
                //**** DEV ****//
                print_r ($temp);
                echo $currentTag . "<br /><br /><br />\n";
                //**** DEV ****//               
                
                //Kijk of er zich tags tussen de tags bevinden (parent -> child)
                if (count ($temp) > 1)
                {
                    //Er zijn childtags gevonden dus de functie gaat zichzelf opnieuw aanroepen
                    $tree = parseTree ($temp, $currentTag);
                    
                    //De sluitingstag wordt erachter gezet
                    if (IsSet ($param) && !empty ($param))
                    {
                        //Met parameters
                        $return .= $settings[$currentTag][0] .
 $param .
 $settings[$currentTag][2] .
 $tree .
 $settings[$currentTag][1];     
                    }
                    else
                    {
                        //Zonder parameters
                        $return .= $settings[$currentTag][0] . $tree . $settings[$currentTag][1];
                    }
                }
                elseif (IsSet ($temp[0]))
                {
                    //Er zijn geen childtags gevonden dus de content wordt geparsed
                    if (IsSet ($settings[$currentTag]))
                    {
                        //Opbouwen
                        if (IsSet ($param) && !empty ($param))
                        {
                            $return .= $settings[$currentTag][0] .
 $param .
 $settings[$currentTag][2] .
 $temp[0] .
 $settings[$currentTag][1];     
                        }
                        else
                        {
                            $return .= $settings[$currentTag][0] . $temp[0] . $settings[$currentTag][1];
                        }
                    }
                }
                
                unset ($temp);
                $currentTag = "";
                $inTag = false;
            }
            elseif ($inTag == true)
            {
                //We zitten tussen de tags in, zet de value op de temp array
                $temp[] = $value;
            }
            else
            {
                //We zitten niet in een tag en zetten de value gelijk op de return
                $return .= $value;
            }
        }
        
        //Kijk of er nog een tag open staat
        if ($inTag == true)
        {
            //Parse childs als dat nodig is
            if (count ($tree) > 1)
            {
                $tree = parseTree ($temp, $currentTag);
            }
            else
            {
                $tree = $temp[0];
            }
            
            //Bouw de juiste html op
            if (IsSet ($param) && !empty ($param))
            {
                $return .= $settings[$currentTag][0] . $param .
 $settings[$currentTag][2] .
 $tree .
 $settings[$currentTag][1];     
            }
            else
            {
                $return .= $settings[$currentTag][0] . $tree . $settings[$currentTag][1];
            }
            
            unset ($temp);
            $inTag = false;
            $currentTag = "";
        }       
    }
    else
    {
        //Geen tags aangetroffen
        $return .= $input[0];
    }
    
    //Bouw de nieuwe output op
    if (IsSet ($currOutput) && !empty ($currOutput))
    {
        $returnedVal = $output;
        $output = "";
        $output = $currOutput . $returnedVal;       
        unset ($currOutput);
    }
    
    return $return;
}

[ Voor 28% gewijzigd door Tux op 26-04-2003 13:35 ]

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

Verwijderd

Zeg, ik heb niets gedaan met jouw code. Het is iets te groot om zo snel te kunnen begrijpen. Maar... ik heb even snel een paar functies gemaakt om een UBB-style tekst te kunnen parsen naar een array. Die array kan je dan weer parsen naar HTML. Die extra stap lijkt me wel handig, vooral als je je assortiment UBB-tags wilt uitbreiden. Deze code werkt dan in elk geval altijd.

Het enige minpuntje is dat hij nog geen support heeft voor attributes in de tag, maar dat kan je vrij eenvoudig inbouwen in de parseTag()-functie.

De comment moet het wel duidelijk maken.

edit:
Oh ja, je tags kunnen natuurlijk oneindig diep genest zijn. De error reporting is overigens gelijk aan 0, d.w.z., je moet er nog wel wat aan doen om het goed bruikbaar te maken.


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?
function parseTree( $str ) {
  //we gaan de hele string letter voor letter af
  for ( $i=0 ; $i<strlen($str) ; $i++ ){
    $char = $str[ $i ];
    
    //als we een tag tegenkomen
    if( $char == '[' ) {
      //gooi alle data hiervoor in de output-array, leeg de databuffer
      if( $text ) $data[] = $text;
      $text = '';
      
      //parse de tag die nu komt
      list( $is_close_tag, $tagname, $length ) = parseTag( substr( $str, $i ) );
      
      //schuif een eindje op in de string, zodat we de tag voorbij zijn
      $i += $length;
      
      //als het een sluit-tag ([/...]) is, dan returnen we onze gegevens
      if( $is_close_tag ) {
        return array( $data, $i - 1 );
      }
      //anders gaan we alle onderliggende gegevens van deze tag ophalen
      else {
        //parse de string die nu komt
        list( $subset, $length ) = parseTree( substr( $str, $i ) );
        
        //schuif weer een eindje op in de string, zodat we het hele sub-element 
        //(dus begintag+data+eindtag) voorbij zijn
        $i += $length;
        
        //voeg de sub-data toe aan de output-array
        $data[] = array( $tagname, $subset );
      }
    }
    //als dit geen tag is, voeg de data dan toe aan de databuffer
    else {
      $text .= $char;
    }
  }
  
  //gooi de databuffer in de output-array
  if( $text ) $data[] = $text;
  
  return $data;
}

function parseTag( $str ) {
  //hoe lang is deze tag?
  $length = strpos( $str, ']' ) + 1;
  
  //haal de eerste [ ervan af en trim
  $str = substr( $str, 1 );
  $str = trim( $str );
  
  //als het een sluittag is, schuif dan een stukje op en geef het door
  if($str[0] == '/'){
    $is_close_tag = TRUE;
    $str = substr( $str, 1);
  }
  
  return array( $is_close_tag, substr( $str, 0, strpos( $str, ']' ) ), $length );
}
?>

[ Voor 6% gewijzigd door Verwijderd op 26-04-2003 17:06 ]


Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 16-09 19:01
Ik heb er nu een functie bijgeschreven die aardig werkt :)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$tags = Array ( 'b' => Array ('<b>','</b>'),
                'i' => Array ('<i>','</i>'),
                'u' => Array ('<u>','</u>'),
                's' => Array ('<s>','</s>')
                
              );
$output = "";

function parse ($input)
{
   global $tags, $output;
   foreach ($input as $key => $value)
   {
        if (is_array ($value))
        {
            if (IsSet ($currentTag) && !empty ($currentTag) && count ($value) == 1)
            {
                $output .= $tags[$currentTag][0];
                $output .= $value[0];
                $output .= $tags[$currentTag][1];
                $currentTag = "";
            }
            elseif (IsSet ($currentTag) && !empty ($currentTag) && count ($value) > 1)
            {
                $output .= $tags[$currentTag][0];
                parse ($value);
                $output .= $tags[$currentTag][1];
                $currentTag = "";
            }
            else
            {
                parse ($value);
            }
        }
        else
        {
            if (!empty ($value) && substr ($value, 0, 1) == "[" && substr ($value, -1) == "]")
            {
                $currentTag = substr ($value, 1, strlen ($value) - 2);
            }
            else
            {
                $output .= $value;
            }
        }
    }
    return $output;
}


Ik ga weer verder ontwikkelen :)
Bedankt sbe

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 12:56
Je script is te lang om zo even te begrijpen, maar je zegt dat je dezelfde functie opnieuw aanroept vanuit de functie. Heb je er aan gedacht dat je misschien de eigen variablen aan het overschrijven bent?

Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 16-09 19:01
djluc schreef op 26 April 2003 @ 18:18:
Je script is te lang om zo even te begrijpen, maar je zegt dat je dezelfde functie opnieuw aanroept vanuit de functie. Heb je er aan gedacht dat je misschien de eigen variablen aan het overschrijven bent?
Ik heb een vierdubbele nesting geprobeerd en ik kreeg geen problemen. En ik heb er idd aan gedacht.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 15-09 18:24

dusty

Celebrate Life!

djluc schreef op 26 april 2003 @ 18:18:
Je script is te lang om zo even te begrijpen, maar je zegt dat je dezelfde functie opnieuw aanroept vanuit de functie. Heb je er aan gedacht dat je misschien de eigen variablen aan het overschrijven bent?
Alleen idiote Global-ers en functie &-gebruikers hebben daar last van >:)

[ Voor 4% gewijzigd door dusty op 27-04-2003 11:21 ]

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR

Pagina: 1