PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.4
Independent Analytics – WordPress Analytics Plugin v2.15.4
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / mustangostang / spyc / php4 / spyc.php4
independent-analytics / vendor / mustangostang / spyc / php4 Last commit date
5to4.php 2 years ago spyc.php4 2 years ago test.php4 2 years ago
spyc.php4
1023 lines
1 <?php
2 /**
3 * Spyc -- A Simple PHP YAML Class
4 * @version 0.4.5
5 * @author Vlad Andersen <vlad.andersen@gmail.com>
6 * @author Chris Wanstrath <chris@ozmm.org>
7 * @link http://code.google.com/p/spyc/
8 * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2009 Vlad Andersen
9 * @license http://www.opensource.org/licenses/mit-license.php MIT License
10 * @package Spyc
11 */
12
13 if (!function_exists('spyc_load')) {
14 /**
15 * Parses YAML to array.
16 * @param string $string YAML string.
17 * @return array
18 */
19 function spyc_load ($string) {
20 return Spyc::YAMLLoadString($string);
21 }
22 }
23
24 if (!function_exists('spyc_load_file')) {
25 /**
26 * Parses YAML to array.
27 * @param string $file Path to YAML file.
28 * @return array
29 */
30 function spyc_load_file ($file) {
31 return Spyc::YAMLLoad($file);
32 }
33 }
34
35 /**
36 * The Simple PHP YAML Class.
37 *
38 * This class can be used to read a YAML file and convert its contents
39 * into a PHP array. It currently supports a very limited subsection of
40 * the YAML spec.
41 *
42 * Usage:
43 * <code>
44 * $Spyc = new Spyc;
45 * $array = $Spyc->load($file);
46 * </code>
47 * or:
48 * <code>
49 * $array = Spyc::YAMLLoad($file);
50 * </code>
51 * or:
52 * <code>
53 * $array = spyc_load_file($file);
54 * </code>
55 * @package Spyc
56 */
57 class Spyc {
58
59 // SETTINGS
60
61 /**
62 * Setting this to true will force YAMLDump to enclose any string value in
63 * quotes. False by default.
64 *
65 * @var bool
66 */
67 var $setting_dump_force_quotes = false;
68
69 /**
70 * Setting this to true will forse YAMLLoad to use syck_load function when
71 * possible. False by default.
72 * @var bool
73 */
74 var $setting_use_syck_is_possible = false;
75
76
77
78 /**#@+
79 * @access private
80 * @var mixed
81 */
82 var $_dumpIndent;
83 var $_dumpWordWrap;
84 var $_containsGroupAnchor = false;
85 var $_containsGroupAlias = false;
86 var $path;
87 var $result;
88 var $LiteralPlaceHolder = '___YAML_Literal_Block___';
89 var $SavedGroups = array();
90 var $indent;
91 /**
92 * Path modifier that should be applied after adding current element.
93 * @var array
94 */
95 var $delayedPath = array();
96
97 /**#@+
98 * @access public
99 * @var mixed
100 */
101 var $_nodeId;
102
103 /**
104 * Load a valid YAML string to Spyc.
105 * @param string $input
106 * @return array
107 */
108 function load ($input) {
109 return $this->__loadString($input);
110 }
111
112 /**
113 * Load a valid YAML file to Spyc.
114 * @param string $file
115 * @return array
116 */
117 function loadFile ($file) {
118 return $this->__load($file);
119 }
120
121 /**
122 * Load YAML into a PHP array statically
123 *
124 * The load method, when supplied with a YAML stream (string or file),
125 * will do its best to convert YAML in a file into a PHP array. Pretty
126 * simple.
127 * Usage:
128 * <code>
129 * $array = Spyc::YAMLLoad('lucky.yaml');
130 * print_r($array);
131 * </code>
132 * @access public
133 * @return array
134 * @param string $input Path of YAML file or string containing YAML
135 */
136 function YAMLLoad($input) {
137 $Spyc = new Spyc;
138 return $Spyc->__load($input);
139 }
140
141 /**
142 * Load a string of YAML into a PHP array statically
143 *
144 * The load method, when supplied with a YAML string, will do its best
145 * to convert YAML in a string into a PHP array. Pretty simple.
146 *
147 * Note: use this function if you don't want files from the file system
148 * loaded and processed as YAML. This is of interest to people concerned
149 * about security whose input is from a string.
150 *
151 * Usage:
152 * <code>
153 * $array = Spyc::YAMLLoadString("---\n0: hello world\n");
154 * print_r($array);
155 * </code>
156 * @access public
157 * @return array
158 * @param string $input String containing YAML
159 */
160 function YAMLLoadString($input) {
161 $Spyc = new Spyc;
162 return $Spyc->__loadString($input);
163 }
164
165 /**
166 * Dump YAML from PHP array statically
167 *
168 * The dump method, when supplied with an array, will do its best
169 * to convert the array into friendly YAML. Pretty simple. Feel free to
170 * save the returned string as nothing.yaml and pass it around.
171 *
172 * Oh, and you can decide how big the indent is and what the wordwrap
173 * for folding is. Pretty cool -- just pass in 'false' for either if
174 * you want to use the default.
175 *
176 * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
177 * you can turn off wordwrap by passing in 0.
178 *
179 * @access public
180 * @return string
181 * @param array $array PHP array
182 * @param int $indent Pass in false to use the default, which is 2
183 * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
184 */
185 function YAMLDump($array,$indent = false,$wordwrap = false) {
186 $spyc = new Spyc;
187 return $spyc->dump($array,$indent,$wordwrap);
188 }
189
190
191 /**
192 * Dump PHP array to YAML
193 *
194 * The dump method, when supplied with an array, will do its best
195 * to convert the array into friendly YAML. Pretty simple. Feel free to
196 * save the returned string as tasteful.yaml and pass it around.
197 *
198 * Oh, and you can decide how big the indent is and what the wordwrap
199 * for folding is. Pretty cool -- just pass in 'false' for either if
200 * you want to use the default.
201 *
202 * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
203 * you can turn off wordwrap by passing in 0.
204 *
205 * @access public
206 * @return string
207 * @param array $array PHP array
208 * @param int $indent Pass in false to use the default, which is 2
209 * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
210 */
211 function dump($array,$indent = false,$wordwrap = false) {
212 // Dumps to some very clean YAML. We'll have to add some more features
213 // and options soon. And better support for folding.
214
215 // New features and options.
216 if ($indent === false or !is_numeric($indent)) {
217 $this->_dumpIndent = 2;
218 } else {
219 $this->_dumpIndent = $indent;
220 }
221
222 if ($wordwrap === false or !is_numeric($wordwrap)) {
223 $this->_dumpWordWrap = 40;
224 } else {
225 $this->_dumpWordWrap = $wordwrap;
226 }
227
228 // New YAML document
229 $string = "---\n";
230
231 // Start at the base of the array and move through it.
232 if ($array) {
233 $array = (array)$array;
234 $first_key = key($array);
235
236 $previous_key = -1;
237 foreach ($array as $key => $value) {
238 $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key);
239 $previous_key = $key;
240 }
241 }
242 return $string;
243 }
244
245 /**
246 * Attempts to convert a key / value array item to YAML
247 * @access private
248 * @return string
249 * @param $key The name of the key
250 * @param $value The value of the item
251 * @param $indent The indent of the current node
252 */
253 function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0) {
254 if (is_array($value)) {
255 if (empty ($value))
256 return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key);
257 // It has children. What to do?
258 // Make it the right kind of item
259 $string = $this->_dumpNode($key, NULL, $indent, $previous_key, $first_key);
260 // Add the indent
261 $indent += $this->_dumpIndent;
262 // Yamlize the array
263 $string .= $this->_yamlizeArray($value,$indent);
264 } elseif (!is_array($value)) {
265 // It doesn't have children. Yip.
266 $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key);
267 }
268 return $string;
269 }
270
271 /**
272 * Attempts to convert an array to YAML
273 * @access private
274 * @return string
275 * @param $array The array you want to convert
276 * @param $indent The indent of the current level
277 */
278 function _yamlizeArray($array,$indent) {
279 if (is_array($array)) {
280 $string = '';
281 $previous_key = -1;
282 $first_key = key($array);
283 foreach ($array as $key => $value) {
284 $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key);
285 $previous_key = $key;
286 }
287 return $string;
288 } else {
289 return false;
290 }
291 }
292
293 /**
294 * Returns YAML from a key and a value
295 * @access private
296 * @return string
297 * @param $key The name of the key
298 * @param $value The value of the item
299 * @param $indent The indent of the current node
300 */
301 function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0) {
302 // do some folding here, for blocks
303 if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
304 strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false ||
305 strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || substr ($value, -1, 1) == ':')) {
306 $value = $this->_doLiteralBlock($value,$indent);
307 } else {
308 $value = $this->_doFolding($value,$indent);
309 if (is_bool($value)) {
310 $value = ($value) ? "true" : "false";
311 }
312 }
313
314 if ($value === array()) $value = '[ ]';
315
316 $spaces = str_repeat(' ',$indent);
317
318 if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
319 // It's a sequence
320 $string = $spaces.'- '.$value."\n";
321 } else {
322 if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
323 // It's mapped
324 if (strpos($key, ":") !== false) { $key = '"' . $key . '"'; }
325 $string = $spaces.$key.': '.$value."\n";
326 }
327 return $string;
328 }
329
330 /**
331 * Creates a literal block for dumping
332 * @access private
333 * @return string
334 * @param $value
335 * @param $indent int The value of the indent
336 */
337 function _doLiteralBlock($value,$indent) {
338 if (strpos($value, "\n") === false && strpos($value, "'") === false) {
339 return sprintf ("'%s'", $value);
340 }
341 if (strpos($value, "\n") === false && strpos($value, '"') === false) {
342 return sprintf ('"%s"', $value);
343 }
344 $exploded = explode("\n",$value);
345 $newValue = '|';
346 $indent += $this->_dumpIndent;
347 $spaces = str_repeat(' ',$indent);
348 foreach ($exploded as $line) {
349 $newValue .= "\n" . $spaces . trim($line);
350 }
351 return $newValue;
352 }
353
354 /**
355 * Folds a string of text, if necessary
356 * @access private
357 * @return string
358 * @param $value The string you wish to fold
359 */
360 function _doFolding($value,$indent) {
361 // Don't do anything if wordwrap is set to 0
362
363 if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
364 $indent += $this->_dumpIndent;
365 $indent = str_repeat(' ',$indent);
366 $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
367 $value = ">\n".$indent.$wrapped;
368 } else {
369 if ($this->setting_dump_force_quotes && is_string ($value))
370 $value = '"' . $value . '"';
371 }
372
373
374 return $value;
375 }
376
377 // LOADING FUNCTIONS
378
379 function __load($input) {
380 $Source = $this->loadFromSource($input);
381 return $this->loadWithSource($Source);
382 }
383
384 function __loadString($input) {
385 $Source = $this->loadFromString($input);
386 return $this->loadWithSource($Source);
387 }
388
389 function loadWithSource($Source) {
390 if (empty ($Source)) return array();
391 if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {
392 $array = syck_load (implode ('', $Source));
393 return is_array($array) ? $array : array();
394 }
395
396 $this->path = array();
397 $this->result = array();
398
399 $cnt = count($Source);
400 for ($i = 0; $i < $cnt; $i++) {
401 $line = $Source[$i];
402
403 $this->indent = strlen($line) - strlen(ltrim($line));
404 $tempPath = $this->getParentPathByIndent($this->indent);
405 $line = $this->stripIndent($line, $this->indent);
406 if ($this->isComment($line)) continue;
407 if ($this->isEmpty($line)) continue;
408 $this->path = $tempPath;
409
410 $literalBlockStyle = $this->startsLiteralBlock($line);
411 if ($literalBlockStyle) {
412 $line = rtrim ($line, $literalBlockStyle . " \n");
413 $literalBlock = '';
414 $line .= $this->LiteralPlaceHolder;
415
416 while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
417 $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle);
418 }
419 $i--;
420 }
421
422 while (++$i < $cnt && $this->greedilyNeedNextLine($line)) {
423 $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
424 }
425 $i--;
426
427
428
429 if (strpos ($line, '#')) {
430 if (strpos ($line, '"') === false && strpos ($line, "'") === false)
431 $line = preg_replace('/\s+#(.+)$/','',$line);
432 }
433
434 $lineArray = $this->_parseLine($line);
435
436 if ($literalBlockStyle)
437 $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
438
439 $this->addArray($lineArray, $this->indent);
440
441 foreach ($this->delayedPath as $indent => $delayedPath)
442 $this->path[$indent] = $delayedPath;
443
444 $this->delayedPath = array();
445
446 }
447 return $this->result;
448 }
449
450 function loadFromSource ($input) {
451 if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
452 return file($input);
453
454 return $this->loadFromString($input);
455 }
456
457 function loadFromString ($input) {
458 $lines = explode("\n",$input);
459 foreach ($lines as $k => $_) {
460 $lines[$k] = rtrim ($_, "\r");
461 }
462 return $lines;
463 }
464
465 /**
466 * Parses YAML code and returns an array for a node
467 * @access private
468 * @return array
469 * @param string $line A line from the YAML file
470 */
471 function _parseLine($line) {
472 if (!$line) return array();
473 $line = trim($line);
474
475 if (!$line) return array();
476 $array = array();
477
478 $group = $this->nodeContainsGroup($line);
479 if ($group) {
480 $this->addGroup($line, $group);
481 $line = $this->stripGroup ($line, $group);
482 }
483
484 if ($this->startsMappedSequence($line))
485 return $this->returnMappedSequence($line);
486
487 if ($this->startsMappedValue($line))
488 return $this->returnMappedValue($line);
489
490 if ($this->isArrayElement($line))
491 return $this->returnArrayElement($line);
492
493 if ($this->isPlainArray($line))
494 return $this->returnPlainArray($line);
495
496
497 return $this->returnKeyValuePair($line);
498
499 }
500
501 /**
502 * Finds the type of the passed value, returns the value as the new type.
503 * @access private
504 * @param string $value
505 * @return mixed
506 */
507 function _toType($value) {
508 if ($value === '') return null;
509 $first_character = $value[0];
510 $last_character = substr($value, -1, 1);
511
512 $is_quoted = false;
513 do {
514 if (!$value) break;
515 if ($first_character != '"' && $first_character != "'") break;
516 if ($last_character != '"' && $last_character != "'") break;
517 $is_quoted = true;
518 } while (0);
519
520 if ($is_quoted)
521 return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\''));
522
523 if (strpos($value, ' #') !== false)
524 $value = preg_replace('/\s+#(.+)$/','',$value);
525
526 if ($first_character == '[' && $last_character == ']') {
527 // Take out strings sequences and mappings
528 $innerValue = trim(substr ($value, 1, -1));
529 if ($innerValue === '') return array();
530 $explode = $this->_inlineEscape($innerValue);
531 // Propagate value array
532 $value = array();
533 foreach ($explode as $v) {
534 $value[] = $this->_toType($v);
535 }
536 return $value;
537 }
538
539 if (strpos($value,': ')!==false && $first_character != '{') {
540 $array = explode(': ',$value);
541 $key = trim($array[0]);
542 array_shift($array);
543 $value = trim(implode(': ',$array));
544 $value = $this->_toType($value);
545 return array($key => $value);
546 }
547
548 if ($first_character == '{' && $last_character == '}') {
549 $innerValue = trim(substr ($value, 1, -1));
550 if ($innerValue === '') return array();
551 // Inline Mapping
552 // Take out strings sequences and mappings
553 $explode = $this->_inlineEscape($innerValue);
554 // Propagate value array
555 $array = array();
556 foreach ($explode as $v) {
557 $SubArr = $this->_toType($v);
558 if (empty($SubArr)) continue;
559 if (is_array ($SubArr)) {
560 $array[key($SubArr)] = $SubArr[key($SubArr)]; continue;
561 }
562 $array[] = $SubArr;
563 }
564 return $array;
565 }
566
567 if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
568 return null;
569 }
570
571 if (intval($first_character) > 0 && preg_match ('/^[1-9]+[0-9]*$/', $value)) {
572 $intvalue = (int)$value;
573 if ($intvalue != PHP_INT_MAX)
574 $value = $intvalue;
575 return $value;
576 }
577
578 if (in_array($value,
579 array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) {
580 return true;
581 }
582
583 if (in_array(strtolower($value),
584 array('false', 'off', '-', 'no', 'n'))) {
585 return false;
586 }
587
588 if (is_numeric($value)) {
589 if ($value === '0') return 0;
590 if (trim ($value, 0) === $value)
591 $value = (float)$value;
592 return $value;
593 }
594
595 return $value;
596 }
597
598 /**
599 * Used in inlines to check for more inlines or quoted strings
600 * @access private
601 * @return array
602 */
603 function _inlineEscape($inline) {
604 // There's gotta be a cleaner way to do this...
605 // While pure sequences seem to be nesting just fine,
606 // pure mappings and mappings with sequences inside can't go very
607 // deep. This needs to be fixed.
608
609 $seqs = array();
610 $maps = array();
611 $saved_strings = array();
612
613 // Check for strings
614 $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
615 if (preg_match_all($regex,$inline,$strings)) {
616 $saved_strings = $strings[0];
617 $inline = preg_replace($regex,'YAMLString',$inline);
618 }
619 unset($regex);
620
621 $i = 0;
622 do {
623
624 // Check for sequences
625 while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) {
626 $seqs[] = $matchseqs[0];
627 $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);
628 }
629
630 // Check for mappings
631 while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) {
632 $maps[] = $matchmaps[0];
633 $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);
634 }
635
636 if ($i++ >= 10) break;
637
638 } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
639
640 $explode = explode(', ',$inline);
641 $stringi = 0; $i = 0;
642
643 while (1) {
644
645 // Re-add the sequences
646 if (!empty($seqs)) {
647 foreach ($explode as $key => $value) {
648 if (strpos($value,'YAMLSeq') !== false) {
649 foreach ($seqs as $seqk => $seq) {
650 $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);
651 $value = $explode[$key];
652 }
653 }
654 }
655 }
656
657 // Re-add the mappings
658 if (!empty($maps)) {
659 foreach ($explode as $key => $value) {
660 if (strpos($value,'YAMLMap') !== false) {
661 foreach ($maps as $mapk => $map) {
662 $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);
663 $value = $explode[$key];
664 }
665 }
666 }
667 }
668
669
670 // Re-add the strings
671 if (!empty($saved_strings)) {
672 foreach ($explode as $key => $value) {
673 while (strpos($value,'YAMLString') !== false) {
674 $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);
675 unset($saved_strings[$stringi]);
676 ++$stringi;
677 $value = $explode[$key];
678 }
679 }
680 }
681
682 $finished = true;
683 foreach ($explode as $key => $value) {
684 if (strpos($value,'YAMLSeq') !== false) {
685 $finished = false; break;
686 }
687 if (strpos($value,'YAMLMap') !== false) {
688 $finished = false; break;
689 }
690 if (strpos($value,'YAMLString') !== false) {
691 $finished = false; break;
692 }
693 }
694 if ($finished) break;
695
696 $i++;
697 if ($i > 10)
698 break; // Prevent infinite loops.
699 }
700
701 return $explode;
702 }
703
704 function literalBlockContinues ($line, $lineIndent) {
705 if (!trim($line)) return true;
706 if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;
707 return false;
708 }
709
710 function referenceContentsByAlias ($alias) {
711 do {
712 if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; }
713 $groupPath = $this->SavedGroups[$alias];
714 $value = $this->result;
715 foreach ($groupPath as $k) {
716 $value = $value[$k];
717 }
718 } while (false);
719 return $value;
720 }
721
722 function addArrayInline ($array, $indent) {
723 $CommonGroupPath = $this->path;
724 if (empty ($array)) return false;
725
726 foreach ($array as $k => $_) {
727 $this->addArray(array($k => $_), $indent);
728 $this->path = $CommonGroupPath;
729 }
730 return true;
731 }
732
733 function addArray ($incoming_data, $incoming_indent) {
734
735 // print_r ($incoming_data);
736
737 if (count ($incoming_data) > 1)
738 return $this->addArrayInline ($incoming_data, $incoming_indent);
739
740 $key = key ($incoming_data);
741 $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
742 if ($key === '__!YAMLZero') $key = '0';
743
744 if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.
745 if ($key || $key === '' || $key === '0') {
746 $this->result[$key] = $value;
747 } else {
748 $this->result[] = $value; end ($this->result); $key = key ($this->result);
749 }
750 $this->path[$incoming_indent] = $key;
751 return;
752 }
753
754
755
756 $history = array();
757 // Unfolding inner array tree.
758 $history[] = $_arr = $this->result;
759 foreach ($this->path as $k) {
760 $history[] = $_arr = $_arr[$k];
761 }
762
763 if ($this->_containsGroupAlias) {
764 $value = $this->referenceContentsByAlias($this->_containsGroupAlias);
765 $this->_containsGroupAlias = false;
766 }
767
768
769 // Adding string or numeric key to the innermost level or $this->arr.
770 if (is_string($key) && $key == '<<') {
771 if (!is_array ($_arr)) { $_arr = array (); }
772 $_arr = array_merge ($_arr, $value);
773 } else if ($key || $key === '' || $key === '0') {
774 $_arr[$key] = $value;
775 } else {
776 if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
777 else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
778 }
779
780 $reverse_path = array_reverse($this->path);
781 $reverse_history = array_reverse ($history);
782 $reverse_history[0] = $_arr;
783 $cnt = count($reverse_history) - 1;
784 for ($i = 0; $i < $cnt; $i++) {
785 $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];
786 }
787 $this->result = $reverse_history[$cnt];
788
789 $this->path[$incoming_indent] = $key;
790
791 if ($this->_containsGroupAnchor) {
792 $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
793 if (is_array ($value)) {
794 $k = key ($value);
795 if (!is_int ($k)) {
796 $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
797 }
798 }
799 $this->_containsGroupAnchor = false;
800 }
801
802 }
803
804 function startsLiteralBlock ($line) {
805 $lastChar = substr (trim($line), -1);
806 if ($lastChar != '>' && $lastChar != '|') return false;
807 if ($lastChar == '|') return $lastChar;
808 // HTML tags should not be counted as literal blocks.
809 if (preg_match ('#<.*?>$#', $line)) return false;
810 return $lastChar;
811 }
812
813 function greedilyNeedNextLine($line) {
814 $line = trim ($line);
815 if (!strlen($line)) return false;
816 if (substr ($line, -1, 1) == ']') return false;
817 if ($line[0] == '[') return true;
818 if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true;
819 return false;
820 }
821
822 function addLiteralLine ($literalBlock, $line, $literalBlockStyle) {
823 $line = $this->stripIndent($line);
824 $line = rtrim ($line, "\r\n\t ") . "\n";
825 if ($literalBlockStyle == '|') {
826 return $literalBlock . $line;
827 }
828 if (strlen($line) == 0)
829 return rtrim($literalBlock, ' ') . "\n";
830 if ($line == "\n" && $literalBlockStyle == '>') {
831 return rtrim ($literalBlock, " \t") . "\n";
832 }
833 if ($line != "\n")
834 $line = trim ($line, "\r\n ") . " ";
835 return $literalBlock . $line;
836 }
837
838 function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
839 foreach ($lineArray as $k => $_) {
840 if (is_array($_))
841 $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);
842 else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
843 $lineArray[$k] = rtrim ($literalBlock, " \r\n");
844 }
845 return $lineArray;
846 }
847
848 function stripIndent ($line, $indent = -1) {
849 if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));
850 return substr ($line, $indent);
851 }
852
853 function getParentPathByIndent ($indent) {
854 if ($indent == 0) return array();
855 $linePath = $this->path;
856 do {
857 end($linePath); $lastIndentInParentPath = key($linePath);
858 if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
859 } while ($indent <= $lastIndentInParentPath);
860 return $linePath;
861 }
862
863
864 function clearBiggerPathValues ($indent) {
865
866
867 if ($indent == 0) $this->path = array();
868 if (empty ($this->path)) return true;
869
870 foreach ($this->path as $k => $_) {
871 if ($k > $indent) unset ($this->path[$k]);
872 }
873
874 return true;
875 }
876
877
878 function isComment ($line) {
879 if (!$line) return false;
880 if ($line[0] == '#') return true;
881 if (trim($line, " \r\n\t") == '---') return true;
882 return false;
883 }
884
885 function isEmpty ($line) {
886 return (trim ($line) === '');
887 }
888
889
890 function isArrayElement ($line) {
891 if (!$line) return false;
892 if ($line[0] != '-') return false;
893 if (strlen ($line) > 3)
894 if (substr($line,0,3) == '---') return false;
895
896 return true;
897 }
898
899 function isHashElement ($line) {
900 return strpos($line, ':');
901 }
902
903 function isLiteral ($line) {
904 if ($this->isArrayElement($line)) return false;
905 if ($this->isHashElement($line)) return false;
906 return true;
907 }
908
909
910 function unquote ($value) {
911 if (!$value) return $value;
912 if (!is_string($value)) return $value;
913 if ($value[0] == '\'') return trim ($value, '\'');
914 if ($value[0] == '"') return trim ($value, '"');
915 return $value;
916 }
917
918 function startsMappedSequence ($line) {
919 return ($line[0] == '-' && substr ($line, -1, 1) == ':');
920 }
921
922 function returnMappedSequence ($line) {
923 $array = array();
924 $key = $this->unquote(trim(substr($line,1,-1)));
925 $array[$key] = array();
926 $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);
927 return array($array);
928 }
929
930 function returnMappedValue ($line) {
931 $array = array();
932 $key = $this->unquote (trim(substr($line,0,-1)));
933 $array[$key] = '';
934 return $array;
935 }
936
937 function startsMappedValue ($line) {
938 return (substr ($line, -1, 1) == ':');
939 }
940
941 function isPlainArray ($line) {
942 return ($line[0] == '[' && substr ($line, -1, 1) == ']');
943 }
944
945 function returnPlainArray ($line) {
946 return $this->_toType($line);
947 }
948
949 function returnKeyValuePair ($line) {
950 $array = array();
951 $key = '';
952 if (strpos ($line, ':')) {
953 // It's a key/value pair most likely
954 // If the key is in double quotes pull it out
955 if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
956 $value = trim(str_replace($matches[1],'',$line));
957 $key = $matches[2];
958 } else {
959 // Do some guesswork as to the key and the value
960 $explode = explode(':',$line);
961 $key = trim($explode[0]);
962 array_shift($explode);
963 $value = trim(implode(':',$explode));
964 }
965 // Set the type of the value. Int, string, etc
966 $value = $this->_toType($value);
967 if ($key === '0') $key = '__!YAMLZero';
968 $array[$key] = $value;
969 } else {
970 $array = array ($line);
971 }
972 return $array;
973
974 }
975
976
977 function returnArrayElement ($line) {
978 if (strlen($line) <= 1) return array(array()); // Weird %)
979 $array = array();
980 $value = trim(substr($line,1));
981 $value = $this->_toType($value);
982 $array[] = $value;
983 return $array;
984 }
985
986
987 function nodeContainsGroup ($line) {
988 $symbolsForReference = 'A-z0-9_\-';
989 if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
990 if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
991 if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
992 if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];
993 if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];
994 if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1];
995 return false;
996
997 }
998
999 function addGroup ($line, $group) {
1000 if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);
1001 if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);
1002 //print_r ($this->path);
1003 }
1004
1005 function stripGroup ($line, $group) {
1006 $line = trim(str_replace($group, '', $line));
1007 return $line;
1008 }
1009 }
1010
1011 // Enable use of Spyc from command line
1012 // The syntax is the following: php spyc.php spyc.yaml
1013
1014 define ('SPYC_FROM_COMMAND_LINE', false);
1015
1016 do {
1017 if (!SPYC_FROM_COMMAND_LINE) break;
1018 if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;
1019 if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break;
1020 $file = $argv[1];
1021 printf ("Spyc loading file: %s\n", $file);
1022 print_r (spyc_load_file ($file));
1023 } while (0);