ApiFormatYaml_spyc.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. /**
  3. * Spyc -- A Simple PHP YAML Class
  4. * @version 0.2.3 -- 2006-02-04
  5. * @author Chris Wanstrath <chris@ozmm.org>
  6. * @see http://spyc.sourceforge.net/
  7. * @copyright Copyright 2005-2006 Chris Wanstrath
  8. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  9. */
  10. /**
  11. * The Simple PHP YAML Class.
  12. *
  13. * This class can be used to read a YAML file and convert its contents
  14. * into a PHP array. It currently supports a very limited subsection of
  15. * the YAML spec.
  16. *
  17. * @ingroup API
  18. */
  19. class Spyc {
  20. /**
  21. * Dump YAML from PHP array statically
  22. *
  23. * The dump method, when supplied with an array, will do its best
  24. * to convert the array into friendly YAML. Pretty simple. Feel free to
  25. * save the returned string as nothing.yml and pass it around.
  26. *
  27. * Oh, and you can decide how big the indent is and what the wordwrap
  28. * for folding is. Pretty cool -- just pass in 'false' for either if
  29. * you want to use the default.
  30. *
  31. * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
  32. * you can turn off wordwrap by passing in 0.
  33. *
  34. * @return string
  35. * @param $array Array: PHP array
  36. * @param $indent Integer: Pass in false to use the default, which is 2
  37. * @param $wordwrap Integer: Pass in 0 for no wordwrap, false for default (40)
  38. */
  39. public static function YAMLDump($array,$indent = false,$wordwrap = false) {
  40. $spyc = new Spyc;
  41. return $spyc->dump($array,$indent,$wordwrap);
  42. }
  43. /**
  44. * Dump PHP array to YAML
  45. *
  46. * The dump method, when supplied with an array, will do its best
  47. * to convert the array into friendly YAML. Pretty simple. Feel free to
  48. * save the returned string as tasteful.yml and pass it around.
  49. *
  50. * Oh, and you can decide how big the indent is and what the wordwrap
  51. * for folding is. Pretty cool -- just pass in 'false' for either if
  52. * you want to use the default.
  53. *
  54. * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
  55. * you can turn off wordwrap by passing in 0.
  56. *
  57. * @public
  58. * @return string
  59. * @param $array Array: PHP array
  60. * @param $indent Integer: Pass in false to use the default, which is 2
  61. * @param $wordwrap Integer: Pass in 0 for no wordwrap, false for default (40)
  62. */
  63. function dump($array,$indent = false,$wordwrap = false) {
  64. // Dumps to some very clean YAML. We'll have to add some more features
  65. // and options soon. And better support for folding.
  66. // New features and options.
  67. if ($indent === false or !is_numeric($indent)) {
  68. $this->_dumpIndent = 2;
  69. } else {
  70. $this->_dumpIndent = $indent;
  71. }
  72. if ($wordwrap === false or !is_numeric($wordwrap)) {
  73. $this->_dumpWordWrap = 40;
  74. } else {
  75. $this->_dumpWordWrap = $wordwrap;
  76. }
  77. // New YAML document
  78. $string = "---\n";
  79. // Start at the base of the array and move through it.
  80. foreach ($array as $key => $value) {
  81. $string .= $this->_yamlize($key,$value,0);
  82. }
  83. return $string;
  84. }
  85. /**** Private Properties ****/
  86. private $_haveRefs;
  87. private $_allNodes;
  88. private $_lastIndent;
  89. private $_lastNode;
  90. private $_inBlock;
  91. private $_isInline;
  92. private $_dumpIndent;
  93. private $_dumpWordWrap;
  94. /**** Private Methods ****/
  95. /**
  96. * Attempts to convert a key / value array item to YAML
  97. * @return string
  98. * @param $key The name of the key
  99. * @param $value The value of the item
  100. * @param $indent The indent of the current node
  101. */
  102. private function _yamlize($key,$value,$indent) {
  103. if (is_array($value)) {
  104. // It has children. What to do?
  105. // Make it the right kind of item
  106. $string = $this->_dumpNode($key,NULL,$indent);
  107. // Add the indent
  108. $indent += $this->_dumpIndent;
  109. // Yamlize the array
  110. $string .= $this->_yamlizeArray($value,$indent);
  111. } elseif (!is_array($value)) {
  112. // It doesn't have children. Yip.
  113. $string = $this->_dumpNode($key,$value,$indent);
  114. }
  115. return $string;
  116. }
  117. /**
  118. * Attempts to convert an array to YAML
  119. * @return string
  120. * @param $array The array you want to convert
  121. * @param $indent The indent of the current level
  122. */
  123. private function _yamlizeArray($array,$indent) {
  124. if (is_array($array)) {
  125. $string = '';
  126. foreach ($array as $key => $value) {
  127. $string .= $this->_yamlize($key,$value,$indent);
  128. }
  129. return $string;
  130. } else {
  131. return false;
  132. }
  133. }
  134. /**
  135. * Find out whether a string needs to be output as a literal rather than in plain style.
  136. * Added by Roan Kattouw 13-03-2008
  137. * @param $value The string to check
  138. * @return bool
  139. */
  140. function _needLiteral($value) {
  141. # Check whether the string contains # or : or begins with any of:
  142. # [ - ? , [ ] { } ! * & | > ' " % @ ` ]
  143. # or is a number or contains newlines
  144. return (bool)(gettype($value) == "string" &&
  145. (is_numeric($value) ||
  146. strpos($value, "\n") ||
  147. preg_match("/[#:]/", $value) ||
  148. preg_match("/^[-?,[\]{}!*&|>'\"%@`]/", $value)));
  149. }
  150. /**
  151. * Returns YAML from a key and a value
  152. * @return string
  153. * @param $key The name of the key
  154. * @param $value The value of the item
  155. * @param $indent The indent of the current node
  156. */
  157. private function _dumpNode($key,$value,$indent) {
  158. // do some folding here, for blocks
  159. if ($this->_needLiteral($value)) {
  160. $value = $this->_doLiteralBlock($value,$indent);
  161. } else {
  162. $value = $this->_doFolding($value,$indent);
  163. }
  164. $spaces = str_repeat(' ',$indent);
  165. if (is_int($key)) {
  166. // It's a sequence
  167. if ($value !== '' && !is_null($value))
  168. $string = $spaces.'- '.$value."\n";
  169. else
  170. $string = $spaces . "-\n";
  171. } else {
  172. // It's mapped
  173. if ($value !== '' && !is_null($value))
  174. $string = $spaces . $key . ': ' . $value . "\n";
  175. else
  176. $string = $spaces . $key . ":\n";
  177. }
  178. return $string;
  179. }
  180. /**
  181. * Creates a literal block for dumping
  182. * @return string
  183. * @param $value
  184. * @param $indent int The value of the indent
  185. */
  186. private function _doLiteralBlock($value,$indent) {
  187. $exploded = explode("\n",$value);
  188. $newValue = '|';
  189. $indent += $this->_dumpIndent;
  190. $spaces = str_repeat(' ',$indent);
  191. foreach ($exploded as $line) {
  192. $newValue .= "\n" . $spaces . trim($line);
  193. }
  194. return $newValue;
  195. }
  196. /**
  197. * Folds a string of text, if necessary
  198. * @return string
  199. * @param $value The string you wish to fold
  200. */
  201. private function _doFolding($value,$indent) {
  202. // Don't do anything if wordwrap is set to 0
  203. if ($this->_dumpWordWrap === 0) {
  204. return $value;
  205. }
  206. if (strlen($value) > $this->_dumpWordWrap) {
  207. $indent += $this->_dumpIndent;
  208. $indent = str_repeat(' ',$indent);
  209. $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
  210. $value = ">\n".$indent.$wrapped;
  211. }
  212. return $value;
  213. }
  214. }