C:\xampp2_not used\php\pear\Text\Wiki\Parse\Default\List.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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
<?php

/**
*
* Parses for bulleted and numbered lists.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: List.php 248434 2007-12-17 16:12:25Z justinpatrin $
*
*/

/**
*
* Parses for bulleted and numbered lists.
*
* This class implements a Text_Wiki_Parse to find source text marked as
* a bulleted or numbered list.  In short, if a line starts with '* ' then
* it is a bullet list item; if a line starts with '# ' then it is a
* number list item.  Spaces in front of the * or # indicate an indented
* sub-list.  The list items must be on sequential lines, and may be
* separated by blank lines to improve readability.  Using a non-* non-#
* non-whitespace character at the beginning of a line ends the list.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
*/

class Text_Wiki_Parse_List extends Text_Wiki_Parse {


    
/**
    *
    * The regular expression used to parse the source text and find
    * matches conforming to this rule.  Used by the parse() method.
    *
    * @access public
    *
    * @var string
    *
    * @see parse()
    *
    */

    
var $regex '/^((\*|#)\s.*\n)(?!\2\s|(?:\s+((?:\*|#) |\n)))/Usm';


    
/**
    *
    * Generates a replacement for the matched text.  Token options are:
    *
    * 'type' =>
    *     'bullet_start' : the start of a bullet list
    *     'bullet_end'   : the end of a bullet list
    *     'number_start' : the start of a number list
    *     'number_end'   : the end of a number list
    *     'item_start'   : the start of item text (bullet or number)
    *     'item_end'     : the end of item text (bullet or number)
    *     'unknown'      : unknown type of list or item
    *
    * 'level' => the indent level (0 for the first level, 1 for the
    * second, etc)
    *
    * 'count' => the list item number at this level. not needed for
    * xhtml, but very useful for PDF and RTF.
    *
    * @access public
    *
    * @param array &$matches The array of matches from parse().
    *
    * @return A series of text and delimited tokens marking the different
    * list text and list elements.
    *
    */

    
function process(&$matches)
    {
        
// the replacement text we will return
        
$return '';

        
// the list of post-processing matches
        
$list = array();

        
// a stack of list-start and list-end types; we keep this
        // so that we know what kind of list we're working with
        // (bullet or number) and what indent level we're at.
        
$stack = array();

        
// the item count is the number of list items for any
        // given list-type on the stack
        
$itemcount = array();

        
// have we processed the very first list item?
        
$pastFirst false;

        
// populate $list with this set of matches. $matches[1] is the
        // text matched as a list set by parse().
        
preg_match_all(
            
'=^(\s*)(\*|#)\s(.*)$=Ums',
            
$matches[1],
            
$list,
            
PREG_SET_ORDER
        
);

        
$numSpaces 0;

        
// loop through each list-item element.
        
foreach ($list as $key => $val) {

            
// $val[0] is the full matched list-item line
            // $val[1] is the number of initial spaces (indent level)
            // $val[2] is the list item type (* or #)
            // $val[3] is the list item text

            // how many levels are we indented? (1 means the "root"
            // list level, no indenting.)
            
$level strlen($val[1]) + 1;

            
// get the list item type
            
if ($val[2] == '*') {
                
$type 'bullet';
            } elseif (
$val[2] == '#') {
                
$type 'number';
            } else {
                
$type 'unknown';
            }

            
// get the text of the list item
            
$text $val[3];

            
// add a level to the list?
            
if ($level count($stack)) {

                
//watch for the same # of spaces and reset level
                
if ($level == $numSpaces) {
                    
$level count($stack);
                } else {

                    
$numSpaces $level;

                    
// reset level as sometimes people use too many spaces
                    
$level count($stack) + 1;

                    
// the current indent level is greater than the
                    // number of stack elements, so we must be starting
                    // a new list.  push the new list type onto the
                    // stack...
                    
array_push($stack$type);

                    
// ...and add a list-start token to the return.
                    
$return .= $this->wiki->addToken(
                                                     
$this->rule,
                                                     array(
                                                           
'type' => $type '_list_start',
                                                           
'level' => $level 1
                                                           
)
                                                     );
                }
            }


            
// remove a level from the list?
            
while (count($stack) > $level) {

                
// so we don't keep counting the stack, we set up a temp
                // var for the count.  -1 becuase we're going to pop the
                // stack in the next command.  $tmp will then equal the
                // current level of indent.
                
$tmp count($stack) - 1;

                
// as long as the stack count is greater than the
                // current indent level, we need to end list types.
                // continue adding end-list tokens until the stack count
                // and the indent level are the same.
                
$return .= $this->wiki->addToken(
                    
$this->rule,
                    array (
                        
'type' => array_pop($stack) . '_list_end',
                        
'level' => $tmp
                    
)
                );

                
// reset to the current (previous) list type so that
                // the new list item matches the proper list type.
                
$type $stack[$tmp 1];

                
// reset the item count for the popped indent level
                
unset($itemcount[$tmp 1]);
            }

            
// add to the item count for this list (taking into account
            // which level we are at).
            
if (! isset($itemcount[$level])) {
                
// first count
                
$itemcount[$level] = 0;
            } else {
                
// increment count
                
$itemcount[$level]++;
            }

            
// is this the very first item in the list?
            
if (! $pastFirst) {
                
$first true;
                
$pastFirst true;
            } else {
                
$first false;
            }

            
// create a list-item starting token.
            
$start $this->wiki->addToken(
                
$this->rule,
                array(
                    
'type' => $type '_item_start',
                    
'level' => $level,
                    
'count' => $itemcount[$level],
                    
'first' => $first
                
)
            );

            
// create a list-item ending token.
            
$end $this->wiki->addToken(
                
$this->rule,
                array(
                    
'type' => $type '_item_end',
                    
'level' => $level,
                    
'count' => $itemcount[$level]
                )
            );

            
// add the starting token, list-item text, and ending token
            // to the return.
            
$return .= $start $val[3] . $end;
        }

        
// the last list-item may have been indented.  go through the
        // list-type stack and create end-list tokens until the stack
        // is empty.
        
while (count($stack) > 0) {
            
$return .= $this->wiki->addToken(
                
$this->rule,
                array (
                    
'type' => array_pop($stack) . '_list_end',
                    
'level' => count($stack)
                )
            );
        }

        
// we're done!  send back the replacement text.
        
return "\n\n" $return "\n\n";
    }
}
?>
x

Windows NT KPTV 6.2 build 9200 (Windows Server 2012 Datacenter Edition) i586