Beispiel #1
0
 /**
  * @param LinesBuffer $buffer
  * @param string $filePath
  * @return array|string
  * @throws ParseException
  */
 private function parseYaml(LinesBuffer $buffer, string $filePath)
 {
     //$dirPath    =   dirname($filePath);
     $bufferLines = $buffer->getBufferedData();
     $line = new Line($buffer->getLinesOffset());
     $parsed = [];
     foreach ($bufferLines as $bufferLine) {
         $line->read($bufferLine);
         // Check if buffering
         if ($buffer->isBuffering()) {
             $subBuffer = $buffer->getSubBuffer();
             if ($line->isBlank()) {
                 $buffer->addToBuffer($line->value);
                 continue;
             } elseif ($line->indent > $subBuffer->getIndent()) {
                 $buffer->addToBuffer($line->value);
                 continue;
             } else {
                 $parsed[$subBuffer->getKey()] = $this->parseYaml($subBuffer, $filePath);
             }
             $buffer->clearSubBuffer();
         }
         // Blank Line
         if ($line->isBlank()) {
             continue;
         }
         // Lines must not be indented by tabs
         if ($line->value[0] === "\t") {
             $this->parseError("Line must not be indented by tabs", $filePath, $line->number);
         }
         // Full-line comment
         if (preg_match("/^\\s*\\#.*\$/", $line->value)) {
             continue;
         }
         // Check if line has Key
         if ($line->hasKey()) {
             // Clear inline comment
             $line->clearInlineComment();
             // Split line in Key/Value pair
             $split = preg_split("/:/", $line->value, 2);
             $key = trim($split[0]);
             $value = array_key_exists(1, $split) ? trim($split[1]) : "";
             if (empty($value)) {
                 // Value not found, start buffering...
                 $buffer->createSubBuffer($key, $line->indent, $line->number);
                 continue;
             } else {
                 // Value found, let's parse
                 try {
                     $value = $this->parseValue($value);
                 } catch (ParseException $e) {
                     $this->parseError(sprintf('%s for "%s"', $e->getMessage(), $key), $filePath, $line->number);
                 }
                 if (is_string($value) && in_array($value, [">", "|"])) {
                     // String buffer operators, start buffering...
                     $buffer->createSubBuffer($key, $line->indent, $line->number)->setType($value);
                     continue;
                 } else {
                     $parsed[$key] = $value;
                 }
             }
         } else {
             // Key doesn't exist
             // Check current buffer type
             if (in_array($buffer->getType(), [">", "|"])) {
                 // String buffer
                 // Clean trailing or leading whitespaces
                 $line->clean();
                 $parsed[] = $line->value;
             } else {
                 // Clear inline comment
                 $line->clearInlineComment();
                 // Clean trailing or leading whitespaces
                 $line->clean();
                 if ($line->value[0] === "-") {
                     // Sequence
                     try {
                         $value = $this->parseValue(trim(substr($line->value, 1)));
                     } catch (ParseException $e) {
                         $this->parseError($e->getMessage(), $filePath, $line->number);
                         $value = null;
                         // Script won't reach this, added for sake of IDE
                     }
                     // Check for special cases
                     if ($buffer->getKey() === "imports") {
                         // Yaml imports
                         if (is_string($value)) {
                             try {
                                 $value = Yaml::Parse($this->importPath($value));
                             } catch (YamlException $e) {
                                 $this->parseError(sprintf("%s imported", $e->getMessage()), $filePath, $line->number);
                             }
                         } else {
                             $this->parseError('Variable "imports" must be sequence of Yaml files', $filePath, $line->number);
                         }
                     }
                     $parsed[] = $value;
                     continue;
                 } else {
                     // Irrational string
                     // Ignore?
                 }
             }
         }
     }
     // Check for any sub buffer at end of lines
     if ($buffer->isBuffering()) {
         $subBuffer = $buffer->getSubBuffer();
         $parsed[$subBuffer->getKey()] = $this->parseYaml($subBuffer, $filePath);
     }
     // Final touches, where applicable
     // String buffer...
     if (in_array($buffer->getType(), [">", "|"])) {
         $glue = $buffer->getType() === ">" ? " " : self::EOL;
         $parsed = implode($glue, $parsed);
     }
     // Empty array should be converted to type NULL
     if (count($parsed) === 0) {
         $parsed = null;
     }
     // Result cannot be Empty on no-key buffer
     if (empty($parsed) && empty($buffer->getKey())) {
         throw ParseException::badYamlFile($filePath);
     }
     // Imports should be merged with final result
     if (is_array($parsed)) {
         if (array_key_exists("imports", $parsed) && is_array($parsed["imports"])) {
             $imported = $parsed["imports"];
             unset($parsed["imports"]);
             array_push($imported, $parsed);
             $parsed = call_user_func_array("array_replace_recursive", $imported);
         }
     }
     return $parsed;
 }
Beispiel #2
0
 /**
  * @param string $name
  * @return Language
  * @throws TranslatorException
  */
 public function language(string $name) : Language
 {
     // Check if language YAML file exists, return Extension (.yml|.yaml)
     $yamlFile = $this->languageExists($name, true);
     if ($yamlFile) {
         // Read and parse language file
         $translations = Yaml::Parse($yamlFile, Yaml::OUTPUT_ARRAY);
         $language = new Language($name);
         // Compile all translations in Comely\IO\i18n\Translator\Language object
         try {
             $this->populateTranslations($language, $translations);
         } catch (TranslatorException $e) {
             // Language files must not have anything else but translations
             throw TranslatorException::languageBadFormat($yamlFile);
         }
         return $language;
     } else {
         throw TranslatorException::languageNotFound($name, $this->languagesPath);
     }
 }