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