|
1 <?php |
|
2 |
|
3 /** |
|
4 * |
|
5 * Parse for block-quoted text. |
|
6 * |
|
7 * @category Text |
|
8 * |
|
9 * @package Text_Wiki |
|
10 * |
|
11 * @author Paul M. Jones <pmjones@php.net> |
|
12 * |
|
13 * @license LGPL |
|
14 * |
|
15 * @version $Id: Blockquote.php,v 1.3 2005/02/23 17:38:29 pmjones Exp $ |
|
16 * |
|
17 */ |
|
18 |
|
19 /** |
|
20 * |
|
21 * Parse for block-quoted text. |
|
22 * |
|
23 * Find source text marked as a blockquote, identified by any number of |
|
24 * greater-than signs '>' at the start of the line, followed by a space, |
|
25 * and then the quote text; each '>' indicates an additional level of |
|
26 * quoting. |
|
27 * |
|
28 * @category Text |
|
29 * |
|
30 * @package Text_Wiki |
|
31 * |
|
32 * @author Paul M. Jones <pmjones@php.net> |
|
33 * |
|
34 */ |
|
35 |
|
36 class Text_Wiki_Parse_Blockquote extends Text_Wiki_Parse { |
|
37 |
|
38 |
|
39 /** |
|
40 * |
|
41 * Regex for parsing the source text. |
|
42 * |
|
43 * @access public |
|
44 * |
|
45 * @var string |
|
46 * |
|
47 * @see parse() |
|
48 * |
|
49 */ |
|
50 |
|
51 var $regex = '/\n((\>).*\n)(?!(\>))/Us'; |
|
52 |
|
53 |
|
54 /** |
|
55 * |
|
56 * Generates a replacement for the matched text. |
|
57 * |
|
58 * Token options are: |
|
59 * |
|
60 * 'type' => |
|
61 * 'start' : the start of a blockquote |
|
62 * 'end' : the end of a blockquote |
|
63 * |
|
64 * 'level' => the indent level (0 for the first level, 1 for the |
|
65 * second, etc) |
|
66 * |
|
67 * @access public |
|
68 * |
|
69 * @param array &$matches The array of matches from parse(). |
|
70 * |
|
71 * @return A series of text and delimited tokens marking the different |
|
72 * list text and list elements. |
|
73 * |
|
74 */ |
|
75 |
|
76 function process(&$matches) |
|
77 { |
|
78 // the replacement text we will return to parse() |
|
79 $return = ''; |
|
80 |
|
81 // the list of post-processing matches |
|
82 $list = array(); |
|
83 |
|
84 // $matches[1] is the text matched as a list set by parse(); |
|
85 // create an array called $list that contains a new set of |
|
86 // matches for the various list-item elements. |
|
87 preg_match_all( |
|
88 '=^(\>+) (.*\n)=Ums', |
|
89 $matches[1], |
|
90 $list, |
|
91 PREG_SET_ORDER |
|
92 ); |
|
93 |
|
94 // a stack of starts and ends; we keep this so that we know what |
|
95 // indent level we're at. |
|
96 $stack = array(); |
|
97 |
|
98 // loop through each list-item element. |
|
99 foreach ($list as $key => $val) { |
|
100 |
|
101 // $val[0] is the full matched list-item line |
|
102 // $val[1] is the number of initial '>' chars (indent level) |
|
103 // $val[2] is the quote text |
|
104 |
|
105 // we number levels starting at 1, not zero |
|
106 $level = strlen($val[1]); |
|
107 |
|
108 // get the text of the line |
|
109 $text = $val[2]; |
|
110 |
|
111 // add a level to the list? |
|
112 while ($level > count($stack)) { |
|
113 |
|
114 // the current indent level is greater than the number |
|
115 // of stack elements, so we must be starting a new |
|
116 // level. push the new level onto the stack with a |
|
117 // dummy value (boolean true)... |
|
118 array_push($stack, true); |
|
119 |
|
120 $return .= "\n"; |
|
121 |
|
122 // ...and add a start token to the return. |
|
123 $return .= $this->wiki->addToken( |
|
124 $this->rule, |
|
125 array( |
|
126 'type' => 'start', |
|
127 'level' => $level - 1 |
|
128 ) |
|
129 ); |
|
130 |
|
131 $return .= "\n\n"; |
|
132 } |
|
133 |
|
134 // remove a level? |
|
135 while (count($stack) > $level) { |
|
136 |
|
137 // as long as the stack count is greater than the |
|
138 // current indent level, we need to end list types. |
|
139 // continue adding end-list tokens until the stack count |
|
140 // and the indent level are the same. |
|
141 array_pop($stack); |
|
142 |
|
143 $return .= "\n\n"; |
|
144 |
|
145 $return .= $this->wiki->addToken( |
|
146 $this->rule, |
|
147 array ( |
|
148 'type' => 'end', |
|
149 'level' => count($stack) |
|
150 ) |
|
151 ); |
|
152 |
|
153 $return .= "\n"; |
|
154 } |
|
155 |
|
156 // add the line text. |
|
157 $return .= $text; |
|
158 } |
|
159 |
|
160 // the last line may have been indented. go through the stack |
|
161 // and create end-tokens until the stack is empty. |
|
162 $return .= "\n"; |
|
163 |
|
164 while (count($stack) > 0) { |
|
165 array_pop($stack); |
|
166 $return .= $this->wiki->addToken( |
|
167 $this->rule, |
|
168 array ( |
|
169 'type' => 'end', |
|
170 'level' => count($stack) |
|
171 ) |
|
172 ); |
|
173 } |
|
174 |
|
175 // we're done! send back the replacement text. |
|
176 return "\n$return\n\n"; |
|
177 } |
|
178 } |
|
179 ?> |