1 | <?php |
||
14 | class Parser |
||
15 | { |
||
16 | /** |
||
17 | * The RegEx used to identify Front Matter variables. |
||
18 | */ |
||
19 | const VARIABLE_DEF = '/(?<!\\\\)%([a-zA-Z]+)/'; |
||
20 | |||
21 | /** |
||
22 | * A list of special fields in the Front Matter that will support expansion. |
||
23 | * |
||
24 | * @var string[] |
||
25 | */ |
||
26 | private static $expandableFields = array('permalink'); |
||
27 | |||
28 | /** |
||
29 | * Whether or not an field was expanded into several values. |
||
30 | * |
||
31 | * Only fields specified in $expandableFields will cause this value to be set to true |
||
32 | * |
||
33 | * @var bool |
||
34 | */ |
||
35 | private $expansionUsed; |
||
36 | |||
37 | /** |
||
38 | * The current depth of the recursion for evaluating nested arrays in the Front Matter. |
||
39 | * |
||
40 | * @var int |
||
41 | */ |
||
42 | private $nestingLevel; |
||
43 | |||
44 | /** |
||
45 | * The current hierarchy of the keys that are being evaluated. |
||
46 | * |
||
47 | * Since arrays can be nested, we'll keep track of the keys up until the current depth. This information is used for |
||
48 | * error reporting |
||
49 | * |
||
50 | * @var array |
||
51 | */ |
||
52 | private $yamlKeys; |
||
53 | |||
54 | /** |
||
55 | * The entire Front Matter block; evaluation will happen in place. |
||
56 | * |
||
57 | * @var array |
||
58 | */ |
||
59 | private $frontMatter; |
||
60 | |||
61 | /** |
||
62 | * FrontMatterParser constructor. |
||
63 | * |
||
64 | * @param array $rawFrontMatter |
||
65 | */ |
||
66 | 44 | public function __construct(&$rawFrontMatter) |
|
77 | |||
78 | /** |
||
79 | * True if any fields were expanded in the Front Matter block. |
||
80 | * |
||
81 | * @return bool |
||
82 | */ |
||
83 | 20 | public function hasExpansion() |
|
87 | |||
88 | // |
||
89 | // Special FrontMatter fields |
||
90 | // |
||
91 | |||
92 | /** |
||
93 | * Special treatment for some FrontMatter variables. |
||
94 | */ |
||
95 | 44 | private function handleSpecialFrontMatter() |
|
99 | |||
100 | /** |
||
101 | * Special treatment for the `date` field in FrontMatter that creates three new variables: year, month, day. |
||
102 | */ |
||
103 | 44 | private function handleDateField() |
|
121 | |||
122 | // |
||
123 | // Evaluation |
||
124 | // |
||
125 | |||
126 | /** |
||
127 | * Evaluate an array as Front Matter. |
||
128 | * |
||
129 | * @param array $yaml |
||
130 | */ |
||
131 | 44 | private function evaluateBlock(&$yaml) |
|
161 | |||
162 | /** |
||
163 | * Evaluate an expandable field. |
||
164 | * |
||
165 | * @param string $key |
||
166 | * @param string $fmStatement |
||
167 | * |
||
168 | * @return array |
||
169 | */ |
||
170 | 25 | private function evaluateExpandableField($key, $fmStatement) |
|
196 | |||
197 | /** |
||
198 | * Convert a string or an array into an array of ExpandedValue objects created through "value expansion". |
||
199 | * |
||
200 | * @param string $frontMatterKey The current hierarchy of the Front Matter keys being used |
||
201 | * @param string $expandableValue The Front Matter value that will be expanded |
||
202 | * @param array $arrayVariableNames The Front Matter variable names that reference arrays |
||
203 | * |
||
204 | * @throws YamlUnsupportedVariableException If a multidimensional array is given for value expansion |
||
205 | * |
||
206 | * @return array |
||
207 | */ |
||
208 | 6 | private function evaluateArrayType($frontMatterKey, $expandableValue, $arrayVariableNames) |
|
243 | |||
244 | /** |
||
245 | * Evaluate an string for FrontMatter variables and replace them with the corresponding values. |
||
246 | * |
||
247 | * @param string $key The key of the Front Matter value |
||
248 | * @param string $string The string that will be evaluated |
||
249 | * @param bool $ignoreArrays When set to true, an exception won't be thrown when an array is found with the |
||
250 | * interpolation |
||
251 | * |
||
252 | * @throws YamlUnsupportedVariableException A FrontMatter variable is not an int, float, or string |
||
253 | * |
||
254 | * @return string The final string with variables evaluated |
||
255 | */ |
||
256 | 43 | private function evaluateBasicType($key, $string, $ignoreArrays = false) |
|
279 | |||
280 | // |
||
281 | // Variable management |
||
282 | // |
||
283 | |||
284 | /** |
||
285 | * Get an array of FrontMatter variables in the specified string that need to be interpolated. |
||
286 | * |
||
287 | * @param string $string |
||
288 | * |
||
289 | * @return string[] |
||
290 | */ |
||
291 | 43 | private function getFrontMatterVariables($string) |
|
301 | |||
302 | /** |
||
303 | * Get the value of a FM variable or throw an exception. |
||
304 | * |
||
305 | * @param string $key |
||
306 | * @param string $varName |
||
307 | * |
||
308 | * @throws YamlVariableUndefinedException |
||
309 | * |
||
310 | * @return mixed |
||
311 | */ |
||
312 | 26 | private function getVariableValue($key, $varName) |
|
321 | |||
322 | // |
||
323 | // Utility functions |
||
324 | // |
||
325 | |||
326 | /** |
||
327 | * @param string $epochTime |
||
328 | * |
||
329 | * @return bool|\DateTime |
||
330 | */ |
||
331 | 6 | private function castDateTimeTimezone($epochTime) |
|
339 | |||
340 | /** |
||
341 | * @param $guess |
||
342 | * |
||
343 | * @return bool|\DateTime |
||
344 | */ |
||
345 | 7 | private function guessDateTime($guess) |
|
365 | } |
||
366 |