Index: trunk/extensions/NaturalLanguageList/NaturalLanguageList.php |
— | — | @@ -55,7 +55,7 @@ |
56 | 56 | $wgParserTestFiles[] = dirname( __FILE__ ) . "/nllParserTests.txt"; |
57 | 57 | |
58 | 58 | class NaturalLanguageList { |
59 | | - |
| 59 | + |
60 | 60 | public static function onParserFirstCallInit( $parser ) { |
61 | 61 | $parser->setFunctionHook( |
62 | 62 | 'list', |
— | — | @@ -69,7 +69,15 @@ |
70 | 70 | ); |
71 | 71 | return true; |
72 | 72 | } |
73 | | - |
| 73 | + |
| 74 | + /** |
| 75 | + * Render {{#list:}} |
| 76 | + * |
| 77 | + * @param $parser Parser |
| 78 | + * @param $frame PPFrame_DOM |
| 79 | + * @param $args Array |
| 80 | + * @return wikicode parsed |
| 81 | + */ |
74 | 82 | public static function render( $parser, $frame, $args ) { |
75 | 83 | if ( count( $args ) == 0 ) { |
76 | 84 | return ''; |
— | — | @@ -80,33 +88,39 @@ |
81 | 89 | |
82 | 90 | return $obj->outputList(); |
83 | 91 | } |
84 | | - |
| 92 | + |
| 93 | + /** |
| 94 | + * Render {{#rawlist:}} |
| 95 | + * |
| 96 | + * @param $parser Parser |
| 97 | + * @param $frame PPFrame_DOM |
| 98 | + * @param $args Array |
| 99 | + * @return wikicode parsed |
| 100 | + */ |
85 | 101 | public static function renderRaw ( $parser, $frame, $args ) { |
86 | 102 | if ( count( $args ) == 0 ) { |
87 | 103 | return ''; |
88 | 104 | } |
89 | | - |
90 | | - $obj = new self( $parser, $frame, $args ); |
91 | | - |
| 105 | + $obj = new self( $parser, $frame, $args ); |
| 106 | + # get separator between data |
92 | 107 | $separator = $obj->mArgs[0]; |
93 | | - |
94 | | - $obj->readOptions( true, $separator ); |
95 | | - |
| 108 | + $obj->readOptions( true, $separator ); |
96 | 109 | $obj->readArgs( $separator ); |
97 | 110 | |
98 | 111 | return $obj->outputList(); |
99 | 112 | } |
| 113 | + |
100 | 114 | private $mParser; |
101 | 115 | private $mFrame; |
102 | 116 | public $mArgs; |
103 | 117 | private $mSeparator = null; |
104 | 118 | private $mOptions = array( |
105 | | - 'fieldsperitem' => -1, |
106 | | - 'duplicates' => true, |
107 | | - 'blanks' => false, |
108 | | - 'itemoutput' => null, |
109 | | - 'outputseparator' => null, |
110 | | - 'lastseparator' => null, |
| 119 | + 'fieldsperitem' => -1, # size of pairs |
| 120 | + 'duplicates' => true, # allow same elements to appear |
| 121 | + 'blanks' => false, # allow blank elements to appear |
| 122 | + 'itemoutput' => null, # the format for each element |
| 123 | + 'outputseparator' => null, # the separator between output elements |
| 124 | + 'lastseparator' => null, # the separator between the last two elements |
111 | 125 | ); |
112 | 126 | private $mReaditems = array(); |
113 | 127 | public $mParams = array(); |
— | — | @@ -129,31 +143,41 @@ |
130 | 144 | */ |
131 | 145 | private function outputList() { |
132 | 146 | |
133 | | - // Convert each item from an array into a string according to the format. |
| 147 | + # Convert each item from an array into a string according to the format. |
134 | 148 | $items = array_map( array( $this, 'formatOutputItem' ), $this->mParams ); |
135 | 149 | |
136 | | - // If there's only one item, there are no separators |
| 150 | + # If there's only one item, there are no separators |
137 | 151 | if ( count( $items ) === 1 ) |
138 | 152 | return $items[0]; |
139 | 153 | |
140 | | - // Otherwise remove the last from the list so that we can implode() the remainder |
| 154 | + # Otherwise remove the last from the list so that we can implode() the remainder |
141 | 155 | $last = array_pop( $items ); |
142 | 156 | |
143 | 157 | return implode( $this->mOptions['outputseparator'], $items ) . $this->mOptions['lastseparator'] . $last; |
144 | 158 | } |
145 | 159 | |
146 | | - // Format the input pairs that make up each output item using the given format |
| 160 | + /** |
| 161 | + * Format the input pairs that make up each output item using the given format |
| 162 | + * |
| 163 | + * @param $pair array or string |
| 164 | + * @return string formatted output |
| 165 | + */ |
147 | 166 | private function formatOutputItem( $pair ) { |
148 | 167 | return wfMsgReplaceArgs( $this->mOptions['itemoutput'], $pair ); |
149 | 168 | } |
150 | 169 | |
151 | 170 | /** |
152 | 171 | * Create $this->mParams from $this->mReaditems using $this->mOptions. |
| 172 | + * |
| 173 | + * @param $separator [default:null] Input separator (e.g. ',') |
153 | 174 | */ |
154 | 175 | private function readArgs( $separator=null ) { |
155 | 176 | $items = array(); # array of args to include |
156 | 177 | |
157 | | - $args = $this->mOptions['duplicates'] ? $this->mReaditems : array_unique( $this->mReaditems ); |
| 178 | + # strip read items of duplicate elements if not permitted |
| 179 | + $args = $this->mOptions['duplicates'] |
| 180 | + ? $this->mReaditems |
| 181 | + : array_unique( $this->mReaditems ); |
158 | 182 | |
159 | 183 | foreach ( $args as $arg ) { |
160 | 184 | if ( !$this->mOptions['blanks'] && $arg === '' ) |
— | — | @@ -161,13 +185,13 @@ |
162 | 186 | self::parseArrayItem( $items, $arg, $separator ); |
163 | 187 | } |
164 | 188 | |
165 | | - // Remove the ignored elements from the array |
| 189 | + # Remove the ignored elements from the array |
166 | 190 | $items = array_diff( $items, $this->mIgnores ); |
167 | 191 | |
168 | | - // Split the array into smaller arrays, one for each output item. |
| 192 | + # Split the array into smaller arrays, one for each output item. |
169 | 193 | $this->mParams = array_chunk( $items, $this->mOptions['fieldsperitem'] ); |
170 | 194 | |
171 | | - // Disgard any leftovers, hrm... |
| 195 | + # Disgard any leftovers, hrm... |
172 | 196 | if ( count( end( $this->mParams ) ) != $this->mOptions['fieldsperitem'] ) { |
173 | 197 | array_pop( $this->mParams ); |
174 | 198 | } |
— | — | @@ -176,6 +200,9 @@ |
177 | 201 | |
178 | 202 | /** |
179 | 203 | * Create $this->mOptions and $this->mReaditems from $this->mArgs using $this->mFrame. |
| 204 | + * |
| 205 | + * @param $ignorefirst boolean Ignore first element in case of {{#rawlist:}} |
| 206 | + * @param $separator [default:null] Input separator |
180 | 207 | */ |
181 | 208 | private function readOptions ( $ignorefirst, $separator=null ) { |
182 | 209 | $args = $this->mArgs; |
— | — | @@ -206,7 +233,8 @@ |
207 | 234 | $this->maxDollar = 1; |
208 | 235 | if ( $this->mOptions['itemoutput'] !== null ) { |
209 | 236 | # set $this->maxDollar to the maxmimum found |
210 | | - preg_replace_callback( '/\$([1-9][0-9]*)/', array( $this, 'callbackMaxDollar' ), |
| 237 | + preg_replace_callback( '/\$([1-9][0-9]*)/', |
| 238 | + array( $this, 'callbackMaxDollar' ), |
211 | 239 | $this->mOptions['itemoutput'] ); |
212 | 240 | } |
213 | 241 | $this->mOptions['fieldsperitem'] = $this->maxDollar; |
— | — | @@ -216,21 +244,28 @@ |
217 | 245 | if ( $this->mOptions['outputseparator'] === null ) { |
218 | 246 | |
219 | 247 | $this->mOptions['outputseparator'] = wfMsgNoTrans( 'nll-separator' ); |
220 | | - |
| 248 | + |
221 | 249 | if ( $this->mOptions['lastseparator'] === null ) { |
222 | 250 | $this->mOptions['lastseparator'] = wfMsgNoTrans( 'nll-lastseparator' ); |
223 | 251 | } |
224 | | - |
| 252 | + # set the last separator to the regular separator if the separator is |
| 253 | + # set and the last separator isn't set specifically |
225 | 254 | } else if ( $this->mOptions['lastseparator'] === null ) { |
226 | 255 | $this->mOptions['lastseparator'] = $this->mOptions['outputseparator']; |
227 | 256 | } |
228 | | - |
| 257 | + |
| 258 | + # use the default format if format not set |
229 | 259 | if ( $this->mOptions['itemoutput'] === null ) { |
230 | 260 | $this->mOptions['itemoutput'] = wfMsgNoTrans( 'nll-itemoutput' ); |
231 | 261 | } |
232 | 262 | } |
233 | 263 | |
234 | | - // Used to find the highest $n in a string |
| 264 | + /** |
| 265 | + * Find the highest $n in a string |
| 266 | + * |
| 267 | + * @param $m Array (object, number) |
| 268 | + * @return object |
| 269 | + */ |
235 | 270 | private function callbackMaxDollar( $m ) { |
236 | 271 | $this->maxDollar = max( $this->maxDollar, $m[1] ); |
237 | 272 | return $m[0]; |
— | — | @@ -241,6 +276,10 @@ |
242 | 277 | * and decides whether it is an option or not. |
243 | 278 | * If it is, then it handles the option (and applies it). |
244 | 279 | * If it isn't, then it just returns the string it found. |
| 280 | + * |
| 281 | + * @param $arg Argument |
| 282 | + * @param $separator Input separator |
| 283 | + * @return Return string if element, else return false |
245 | 284 | */ |
246 | 285 | private function handleInputItem( $arg, $separator=null ) { |
247 | 286 | if ( $arg instanceof PPNode_DOM ) { |
— | — | @@ -292,6 +331,12 @@ |
293 | 332 | return false; |
294 | 333 | } |
295 | 334 | |
| 335 | + /** |
| 336 | + * Using magic to store all known names for each option |
| 337 | + * |
| 338 | + * @param $input string |
| 339 | + * @return The option found; otherwise false |
| 340 | + */ |
296 | 341 | private static function parseOptionName( $value ) { |
297 | 342 | |
298 | 343 | static $magicWords = null; |
— | — | @@ -307,20 +352,39 @@ |
308 | 353 | if ( $name = $magicWords->matchStartToEnd( trim($value) ) ) { |
309 | 354 | return str_replace( 'nll_', '', $name ); |
310 | 355 | } |
311 | | - |
| 356 | + |
| 357 | + # blimey, so not an option!? |
312 | 358 | return false; |
313 | 359 | } |
314 | 360 | |
| 361 | + /** |
| 362 | + * Insert a new element into an array. |
| 363 | + * |
| 364 | + * @param $array The array in question |
| 365 | + * @param $value The element to be inserted |
| 366 | + * @param $separator [default:null] Input separator |
| 367 | + */ |
315 | 368 | private static function parseArrayItem( &$array, $value, $separator=null ) { |
| 369 | + # if no separator, just assume the value can be appended, |
| 370 | + # simple as that |
316 | 371 | if ( $separator === null ) { |
317 | 372 | $array[] = $value; |
318 | 373 | } else { |
| 374 | + # else, let's break the value up and append |
| 375 | + # each 'subvalue' to the array. |
319 | 376 | $tmp = explode ( $separator, $value ); |
320 | 377 | foreach ( $tmp as $v ) |
321 | 378 | $array[] = $v; |
322 | 379 | } |
323 | 380 | } |
324 | | - |
| 381 | + |
| 382 | + /** |
| 383 | + * Parse numeral |
| 384 | + * |
| 385 | + * @param $value Integer |
| 386 | + * @param $default [default:1] Integer |
| 387 | + * @return The integer if integer and above 0, otherwise $default |
| 388 | + */ |
325 | 389 | private static function parseNumeral( $value, $default = 1 ) { |
326 | 390 | if ( is_numeric( $value ) && $value > 0 ) { |
327 | 391 | return floor( $value ); # only integers |
— | — | @@ -328,12 +392,25 @@ |
329 | 393 | return $default; |
330 | 394 | } |
331 | 395 | |
| 396 | + /** |
| 397 | + * Parse string |
| 398 | + * |
| 399 | + * @param $value String |
| 400 | + * @param $default [default:null] String |
| 401 | + * @return The string, if none found, return $default |
| 402 | + */ |
332 | 403 | private static function parseString( $value, $default = null ) { |
333 | 404 | if ( $value !== '' ) |
334 | 405 | return $value; |
335 | 406 | return $default; |
336 | 407 | } |
337 | 408 | |
| 409 | + /** |
| 410 | + * Parse boolean |
| 411 | + * |
| 412 | + * @param $value String |
| 413 | + * @return true if truth value found; otherwise false |
| 414 | + */ |
338 | 415 | private static function parseBoolean( $value ) { |
339 | 416 | return in_array( $value, array( 1, true, '1', 'true' ), true ); |
340 | 417 | } |