Add initial between point adding prototype
[bus.git] / spyc / spyc.php
blob:a/spyc/spyc.php -> blob:b/spyc/spyc.php
  <?php
  /**
  * Spyc -- A Simple PHP YAML Class
  * @version 0.4.5
  * @author Vlad Andersen <vlad.andersen@gmail.com>
  * @author Chris Wanstrath <chris@ozmm.org>
  * @link http://code.google.com/p/spyc/
  * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2009 Vlad Andersen
  * @license http://www.opensource.org/licenses/mit-license.php MIT License
  * @package Spyc
  */
   
  if (!function_exists('spyc_load')) {
  /**
  * Parses YAML to array.
  * @param string $string YAML string.
  * @return array
  */
  function spyc_load ($string) {
  return Spyc::YAMLLoadString($string);
  }
  }
   
  if (!function_exists('spyc_load_file')) {
  /**
  * Parses YAML to array.
  * @param string $file Path to YAML file.
  * @return array
  */
  function spyc_load_file ($file) {
  return Spyc::YAMLLoad($file);
  }
  }
   
  /**
  * The Simple PHP YAML Class.
  *
  * This class can be used to read a YAML file and convert its contents
  * into a PHP array. It currently supports a very limited subsection of
  * the YAML spec.
  *
  * Usage:
  * <code>
  * $Spyc = new Spyc;
  * $array = $Spyc->load($file);
  * </code>
  * or:
  * <code>
  * $array = Spyc::YAMLLoad($file);
  * </code>
  * or:
  * <code>
  * $array = spyc_load_file($file);
  * </code>
  * @package Spyc
  */
  class Spyc {
   
  // SETTINGS
   
  /**
  * Setting this to true will force YAMLDump to enclose any string value in
  * quotes. False by default.
  *
  * @var bool
  */
  public $setting_dump_force_quotes = false;
   
  /**
  * Setting this to true will forse YAMLLoad to use syck_load function when
  * possible. False by default.
  * @var bool
  */
  public $setting_use_syck_is_possible = false;
   
   
   
  /**#@+
  * @access private
  * @var mixed
  */
  private $_dumpIndent;
  private $_dumpWordWrap;
  private $_containsGroupAnchor = false;
  private $_containsGroupAlias = false;
  private $path;
  private $result;
  private $LiteralPlaceHolder = '___YAML_Literal_Block___';
  private $SavedGroups = array();
  private $indent;
  /**
  * Path modifier that should be applied after adding current element.
  * @var array
  */
  private $delayedPath = array();
   
  /**#@+
  * @access public
  * @var mixed
  */
  public $_nodeId;
   
  /**
  * Load a valid YAML string to Spyc.
  * @param string $input
  * @return array
  */
  public function load ($input) {
  return $this->__loadString($input);
  }
   
  /**
  * Load a valid YAML file to Spyc.
  * @param string $file
  * @return array
  */
  public function loadFile ($file) {
  return $this->__load($file);
  }
   
  /**
  * Load YAML into a PHP array statically
  *
  * The load method, when supplied with a YAML stream (string or file),
  * will do its best to convert YAML in a file into a PHP array. Pretty
  * simple.
  * Usage:
  * <code>
  * $array = Spyc::YAMLLoad('lucky.yaml');
  * print_r($array);
  * </code>
  * @access public
  * @return array
  * @param string $input Path of YAML file or string containing YAML
  */
  public static function YAMLLoad($input) {
  $Spyc = new Spyc;
  return $Spyc->__load($input);
  }
   
  /**
  * Load a string of YAML into a PHP array statically
  *
  * The load method, when supplied with a YAML string, will do its best
  * to convert YAML in a string into a PHP array. Pretty simple.
  *
  * Note: use this function if you don't want files from the file system
  * loaded and processed as YAML. This is of interest to people concerned
  * about security whose input is from a string.
  *
  * Usage:
  * <code>
  * $array = Spyc::YAMLLoadString("---\n0: hello world\n");
  * print_r($array);
  * </code>
  * @access public
  * @return array
  * @param string $input String containing YAML
  */
  public static function YAMLLoadString($input) {
  $Spyc = new Spyc;
  return $Spyc->__loadString($input);
  }
   
  /**
  * Dump YAML from PHP array statically
  *
  * The dump method, when supplied with an array, will do its best
  * to convert the array into friendly YAML. Pretty simple. Feel free to
  * save the returned string as nothing.yaml and pass it around.
  *
  * Oh, and you can decide how big the indent is and what the wordwrap
  * for folding is. Pretty cool -- just pass in 'false' for either if
  * you want to use the default.
  *
  * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
  * you can turn off wordwrap by passing in 0.
  *
  * @access public
  * @return string
  * @param array $array PHP array
  * @param int $indent Pass in false to use the default, which is 2
  * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
  */
  public static function YAMLDump($array,$indent = false,$wordwrap = false) {
  $spyc = new Spyc;
  return $spyc->dump($array,$indent,$wordwrap);
  }
   
   
  /**
  * Dump PHP array to YAML
  *
  * The dump method, when supplied with an array, will do its best
  * to convert the array into friendly YAML. Pretty simple. Feel free to
  * save the returned string as tasteful.yaml and pass it around.
  *
  * Oh, and you can decide how big the indent is and what the wordwrap
  * for folding is. Pretty cool -- just pass in 'false' for either if
  * you want to use the default.
  *
  * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
  * you can turn off wordwrap by passing in 0.
  *
  * @access public
  * @return string
  * @param array $array PHP array
  * @param int $indent Pass in false to use the default, which is 2
  * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
  */
  public function dump($array,$indent = false,$wordwrap = false) {
  // Dumps to some very clean YAML. We'll have to add some more features
  // and options soon. And better support for folding.
   
  // New features and options.
  if ($indent === false or !is_numeric($indent)) {
  $this->_dumpIndent = 2;
  } else {
  $this->_dumpIndent = $indent;
  }
   
  if ($wordwrap === false or !is_numeric($wordwrap)) {
  $this->_dumpWordWrap = 40;
  } else {
  $this->_dumpWordWrap = $wordwrap;
  }
   
  // New YAML document
  $string = "---\n";
   
  // Start at the base of the array and move through it.
  if ($array) {
  $array = (array)$array;
  $first_key = key($array);
   
  $previous_key = -1;
  foreach ($array as $key => $value) {
  $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key);
  $previous_key = $key;
  }
  }
  return $string;
  }
   
  /**
  * Attempts to convert a key / value array item to YAML
  * @access private
  * @return string
  * @param $key The name of the key
  * @param $value The value of the item
  * @param $indent The indent of the current node
  */
  private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0) {
  if (is_array($value)) {
  if (empty ($value))
  return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key);
  // It has children. What to do?
  // Make it the right kind of item
  $string = $this->_dumpNode($key, NULL, $indent, $previous_key, $first_key);
  // Add the indent
  $indent += $this->_dumpIndent;
  // Yamlize the array
  $string .= $this->_yamlizeArray($value,$indent);
  } elseif (!is_array($value)) {
  // It doesn't have children. Yip.
  $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key);
  }
  return $string;
  }
   
  /**
  * Attempts to convert an array to YAML
  * @access private
  * @return string
  * @param $array The array you want to convert
  * @param $indent The indent of the current level
  */
  private function _yamlizeArray($array,$indent) {
  if (is_array($array)) {
  $string = '';
  $previous_key = -1;
  $first_key = key($array);
  foreach ($array as $key => $value) {
  $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key);
  $previous_key = $key;
  }
  return $string;
  } else {
  return false;
  }
  }
   
  /**
  * Returns YAML from a key and a value
  * @access private
  * @return string
  * @param $key The name of the key
  * @param $value The value of the item
  * @param $indent The indent of the current node
  */
  private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0) {
  // do some folding here, for blocks
  if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
  strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false ||
  strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || substr ($value, -1, 1) == ':')) {
  $value = $this->_doLiteralBlock($value,$indent);
  } else {
  $value = $this->_doFolding($value,$indent);
  if (is_bool($value)) {
  $value = ($value) ? "true" : "false";
  }
  }
   
  if ($value === array()) $value = '[ ]';
   
  $spaces = str_repeat(' ',$indent);
   
  if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
  // It's a sequence
  $string = $spaces.'- '.$value."\n";
  } else {
  if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
  // It's mapped
  if (strpos($key, ":") !== false) { $key = '"' . $key . '"'; }
  $string = $spaces.$key.': '.$value."\n";
  }
  return $string;
  }
   
  /**
  * Creates a literal block for dumping
  * @access private
  * @return string
  * @param $value
  * @param $indent int The value of the indent
  */
  private function _doLiteralBlock($value,$indent) {
  if (strpos($value, "\n") === false && strpos($value, "'") === false) {
  return sprintf ("'%s'", $value);
  }
  if (strpos($value, "\n") === false && strpos($value, '"') === false) {
  return sprintf ('"%s"', $value);
  }
  $exploded = explode("\n",$value);
  $newValue = '|';
  $indent += $this->_dumpIndent;
  $spaces = str_repeat(' ',$indent);
  foreach ($exploded as $line) {
  $newValue .= "\n" . $spaces . trim($line);
  }
  return $newValue;
  }
   
  /**
  * Folds a string of text, if necessary
  * @access private
  * @return string
  * @param $value The string you wish to fold
  */
  private function _doFolding($value,$indent) {
  // Don't do anything if wordwrap is set to 0
   
  if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
  $indent += $this->_dumpIndent;
  $indent = str_repeat(' ',$indent);
  $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
  $value = ">\n".$indent.$wrapped;
  } else {
  if ($this->setting_dump_force_quotes && is_string ($value))
  $value = '"' . $value . '"';
  }
   
   
  return $value;
  }
   
  // LOADING FUNCTIONS
   
  private function __load($input) {
  $Source = $this->loadFromSource($input);
  return $this->loadWithSource($Source);
  }
   
  private function __loadString($input) {
  $Source = $this->loadFromString($input);
  return $this->loadWithSource($Source);
  }