11<?php
22/**
33 * Spyc -- A Simple PHP YAML Class
4- * @version 0.4. 5
4+ * @version 0.5
55 * @author Vlad Andersen <vlad.andersen@gmail.com>
66 * @author Chris Wanstrath <chris@ozmm.org>
77 * @link http://code.google.com/p/spyc/
8- * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2009 Vlad Andersen
8+ * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen
99 * @license http://www.opensource.org/licenses/mit-license.php MIT License
1010 * @package Spyc
1111 */
@@ -58,6 +58,8 @@ class Spyc {
5858
5959 // SETTINGS
6060
61+ const REMPTY = "\0\0\0\0\0" ;
62+
6163 /**
6264 * Setting this to true will force YAMLDump to enclose any string value in
6365 * quotes. False by default.
@@ -230,12 +232,11 @@ public function dump($array,$indent = false,$wordwrap = false) {
230232
231233 // Start at the base of the array and move through it.
232234 if ($ array ) {
233- $ array = (array )$ array ;
234- $ first_key = key ($ array );
235-
235+ $ array = (array )$ array ;
236236 $ previous_key = -1 ;
237237 foreach ($ array as $ key => $ value ) {
238- $ string .= $ this ->_yamlize ($ key ,$ value ,0 ,$ previous_key , $ first_key );
238+ if (!isset ($ first_key )) $ first_key = $ key ;
239+ $ string .= $ this ->_yamlize ($ key ,$ value ,0 ,$ previous_key , $ first_key , $ array );
239240 $ previous_key = $ key ;
240241 }
241242 }
@@ -250,20 +251,20 @@ public function dump($array,$indent = false,$wordwrap = false) {
250251 * @param $value The value of the item
251252 * @param $indent The indent of the current node
252253 */
253- private function _yamlize ($ key ,$ value ,$ indent , $ previous_key = -1 , $ first_key = 0 ) {
254+ private function _yamlize ($ key ,$ value ,$ indent , $ previous_key = -1 , $ first_key = 0 , $ source_array = null ) {
254255 if (is_array ($ value )) {
255256 if (empty ($ value ))
256- return $ this ->_dumpNode ($ key , array (), $ indent , $ previous_key , $ first_key );
257+ return $ this ->_dumpNode ($ key , array (), $ indent , $ previous_key , $ first_key, $ source_array );
257258 // It has children. What to do?
258259 // Make it the right kind of item
259- $ string = $ this ->_dumpNode ($ key , NULL , $ indent , $ previous_key , $ first_key );
260+ $ string = $ this ->_dumpNode ($ key , self :: REMPTY , $ indent , $ previous_key , $ first_key, $ source_array );
260261 // Add the indent
261262 $ indent += $ this ->_dumpIndent ;
262263 // Yamlize the array
263264 $ string .= $ this ->_yamlizeArray ($ value ,$ indent );
264265 } elseif (!is_array ($ value )) {
265266 // It doesn't have children. Yip.
266- $ string = $ this ->_dumpNode ($ key , $ value , $ indent , $ previous_key , $ first_key );
267+ $ string = $ this ->_dumpNode ($ key , $ value , $ indent , $ previous_key , $ first_key, $ source_array );
267268 }
268269 return $ string ;
269270 }
@@ -279,9 +280,9 @@ private function _yamlizeArray($array,$indent) {
279280 if (is_array ($ array )) {
280281 $ string = '' ;
281282 $ previous_key = -1 ;
282- $ first_key = key ($ array );
283283 foreach ($ array as $ key => $ value ) {
284- $ string .= $ this ->_yamlize ($ key , $ value , $ indent , $ previous_key , $ first_key );
284+ if (!isset ($ first_key )) $ first_key = $ key ;
285+ $ string .= $ this ->_yamlize ($ key , $ value , $ indent , $ previous_key , $ first_key , $ array );
285286 $ previous_key = $ key ;
286287 }
287288 return $ string ;
@@ -298,31 +299,43 @@ private function _yamlizeArray($array,$indent) {
298299 * @param $value The value of the item
299300 * @param $indent The indent of the current node
300301 */
301- private function _dumpNode ($ key , $ value , $ indent , $ previous_key = -1 , $ first_key = 0 ) {
302+ private function _dumpNode ($ key , $ value , $ indent , $ previous_key = -1 , $ first_key = 0 , $ source_array = null ) {
302303 // do some folding here, for blocks
303304 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 ) == ': ' )) {
305+ strpos ($ value ,"* " ) !== false || strpos ($ value ,"# " ) !== false || strpos ($ value ,"< " ) !== false || strpos ($ value ,"> " ) !== false || strpos ($ value , ' ' ) !== false ||
306+ strpos ($ value ,"[ " ) !== false || strpos ($ value ,"] " ) !== false || strpos ($ value ,"{ " ) !== false || strpos ($ value ,"} " ) !== false ) || strpos ($ value ,"& " ) !== false || strpos ($ value , "' " ) !== false || strpos ($ value , "! " ) === 0 ||
307+ substr ($ value , -1 , 1 ) == ': ' )
308+ ) {
306309 $ value = $ this ->_doLiteralBlock ($ value ,$ indent );
307310 } else {
308311 $ value = $ this ->_doFolding ($ value ,$ indent );
309- if (is_bool ($ value )) {
310- $ value = ($ value ) ? "true " : "false " ;
311- }
312312 }
313313
314314 if ($ value === array ()) $ value = '[ ] ' ;
315+ if (in_array ($ value , array ('true ' , 'TRUE ' , 'false ' , 'FALSE ' , 'y ' , 'Y ' , 'n ' , 'N ' , 'null ' , 'NULL ' ), true )) {
316+ $ value = $ this ->_doLiteralBlock ($ value ,$ indent );
317+ }
318+ if (trim ($ value ) != $ value )
319+ $ value = $ this ->_doLiteralBlock ($ value ,$ indent );
320+
321+ if (is_bool ($ value )) {
322+ $ value = ($ value ) ? "true " : "false " ;
323+ }
324+
325+ if ($ value === null ) $ value = 'null ' ;
326+ if ($ value === "' " . self ::REMPTY . "' " ) $ value = null ;
315327
316328 $ spaces = str_repeat (' ' ,$ indent );
317329
318- if (is_int ($ key ) && $ key - 1 == $ previous_key && $ first_key ===0 ) {
330+ //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
331+ if (is_array ($ source_array ) && array_keys ($ source_array ) === range (0 , count ($ source_array ) - 1 )) {
319332 // It's a sequence
320333 $ string = $ spaces .'- ' .$ value ."\n" ;
321334 } else {
322- if ($ first_key ===0 ) throw new Exception ('Keys are all screwy. The first one was zero, now it \'s " ' . $ key .'" ' );
335+ // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
323336 // It's mapped
324- if (strpos ($ key , ": " ) !== false ) { $ key = '" ' . $ key . '" ' ; }
325- $ string = $ spaces .$ key .': ' .$ value ."\n" ;
337+ if (strpos ($ key , ": " ) !== false || strpos ( $ key , " # " ) !== false ) { $ key = '" ' . $ key . '" ' ; }
338+ $ string = rtrim ( $ spaces .$ key .': ' .$ value) ."\n" ;
326339 }
327340 return $ string ;
328341 }
@@ -335,6 +348,7 @@ private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key
335348 * @param $indent int The value of the indent
336349 */
337350 private function _doLiteralBlock ($ value ,$ indent ) {
351+ if ($ value === "\n" ) return '\n ' ;
338352 if (strpos ($ value , "\n" ) === false && strpos ($ value , "' " ) === false ) {
339353 return sprintf ("'%s' " , $ value );
340354 }
@@ -346,7 +360,7 @@ private function _doLiteralBlock($value,$indent) {
346360 $ indent += $ this ->_dumpIndent ;
347361 $ spaces = str_repeat (' ' ,$ indent );
348362 foreach ($ exploded as $ line ) {
349- $ newValue .= "\n" . $ spaces . trim ($ line );
363+ $ newValue .= "\n" . $ spaces . ($ line );
350364 }
351365 return $ newValue ;
352366 }
@@ -366,7 +380,7 @@ private function _doFolding($value,$indent) {
366380 $ wrapped = wordwrap ($ value ,$ this ->_dumpWordWrap ,"\n$ indent " );
367381 $ value = "> \n" .$ indent .$ wrapped ;
368382 } else {
369- if ($ this ->setting_dump_force_quotes && is_string ($ value ))
383+ if ($ this ->setting_dump_force_quotes && is_string ($ value ) && $ value !== self :: REMPTY )
370384 $ value = '" ' . $ value . '" ' ;
371385 }
372386
@@ -412,9 +426,9 @@ private function loadWithSource($Source) {
412426 $ line = rtrim ($ line , $ literalBlockStyle . " \n" );
413427 $ literalBlock = '' ;
414428 $ line .= $ this ->LiteralPlaceHolder ;
415-
429+ $ literal_block_indent = strlen ( $ Source [ $ i + 1 ]) - strlen ( ltrim ( $ Source [ $ i + 1 ]));
416430 while (++$ i < $ cnt && $ this ->literalBlockContinues ($ Source [$ i ], $ this ->indent )) {
417- $ literalBlock = $ this ->addLiteralLine ($ literalBlock , $ Source [$ i ], $ literalBlockStyle );
431+ $ literalBlock = $ this ->addLiteralLine ($ literalBlock , $ Source [$ i ], $ literalBlockStyle, $ literal_block_indent );
418432 }
419433 $ i --;
420434 }
@@ -471,8 +485,8 @@ private function loadFromString ($input) {
471485 private function _parseLine ($ line ) {
472486 if (!$ line ) return array ();
473487 $ line = trim ($ line );
474-
475488 if (!$ line ) return array ();
489+
476490 $ array = array ();
477491
478492 $ group = $ this ->nodeContainsGroup ($ line );
@@ -520,9 +534,11 @@ private function _toType($value) {
520534 if ($ is_quoted )
521535 return strtr (substr ($ value , 1 , -1 ), array ('\\" ' => '" ' , '\'\'' => '\'' , '\\\'' => '\'' ));
522536
523- if (strpos ($ value , ' # ' ) !== false )
537+ if (strpos ($ value , ' # ' ) !== false && ! $ is_quoted )
524538 $ value = preg_replace ('/\s+#(.+)$/ ' ,'' ,$ value );
525539
540+ if (!$ is_quoted ) $ value = str_replace ('\n ' , "\n" , $ value );
541+
526542 if ($ first_character == '[ ' && $ last_character == '] ' ) {
527543 // Take out strings sequences and mappings
528544 $ innerValue = trim (substr ($ value , 1 , -1 ));
@@ -568,7 +584,7 @@ private function _toType($value) {
568584 return null ;
569585 }
570586
571- if (intval ( $ first_character ) > 0 && preg_match ('/^[1-9]+[0-9]*$/ ' , $ value )) {
587+ if ( is_numeric ( $ value ) && preg_match ('/^(-|) [1-9]+[0-9]*$/ ' , $ value ) ) {
572588 $ intvalue = (int )$ value ;
573589 if ($ intvalue != PHP_INT_MAX )
574590 $ value = $ intvalue ;
@@ -587,7 +603,7 @@ private function _toType($value) {
587603
588604 if (is_numeric ($ value )) {
589605 if ($ value === '0 ' ) return 0 ;
590- if (trim ($ value , 0 ) === $ value )
606+ if (rtrim ($ value , 0 ) === $ value )
591607 $ value = (float )$ value ;
592608 return $ value ;
593609 }
@@ -772,7 +788,10 @@ private function addArray ($incoming_data, $incoming_indent) {
772788
773789 $ _arr = array_merge ($ _arr , $ value );
774790 } else if ($ key || $ key === '' || $ key === '0 ' ) {
775- $ _arr [$ key ] = $ value ;
791+ if (!is_array ($ _arr ))
792+ $ _arr = array ($ key =>$ value );
793+ else
794+ $ _arr [$ key ] = $ value ;
776795 } else {
777796 if (!is_array ($ _arr )) { $ _arr = array ($ value ); $ key = 0 ; }
778797 else { $ _arr [] = $ value ; end ($ _arr ); $ key = key ($ _arr ); }
@@ -820,8 +839,11 @@ private static function greedilyNeedNextLine($line) {
820839 return false ;
821840 }
822841
823- private function addLiteralLine ($ literalBlock , $ line , $ literalBlockStyle ) {
824- $ line = self ::stripIndent ($ line );
842+ private function addLiteralLine ($ literalBlock , $ line , $ literalBlockStyle , $ indent = -1 ) {
843+ $ line = self ::stripIndent ($ line , $ indent );
844+ if ($ literalBlockStyle !== '| ' ) {
845+ $ line = self ::stripIndent ($ line );
846+ }
825847 $ line = rtrim ($ line , "\r\n\t " ) . "\n" ;
826848 if ($ literalBlockStyle == '| ' ) {
827849 return $ literalBlock . $ line ;
0 commit comments