Replaces a next placeholder in the pattern

@param array $matches
@return string
@throws \go\DB\Exceptions\Templater
500475
protected function placeholderClb($matches)
    {
        $placeholder = isset($matches[1]) ? $matches[1] : '';
        if (isset($matches[3])) {
            $name = $matches[3];
            if (empty($name)) {
                /* There is a named placeholder without name ("?set:") */
                throw new UnknownPlaceholder($matches[0]);
            }
        } else {
            $name = null;
            if ($placeholder == '?') { // "??" for question mark
                return '?';
            }
        }
        if ($name) {
            if ($this->counter == 0) {
                $this->named = true;
            } elseif (!$this->named) {
                /* There is a named placeholder although already used regular */
                throw new MixedPlaceholder($matches[0]);
            }
            if (!array_key_exists($name, $this->data)) {
                throw new DataNamed($name);
            }
            $value = $this->data[$name];
        } elseif ($this->named) {
            /* There is a regular placeholder although already used named */
            throw new MixedPlaceholder($matches[0]);
        } else {
            if (!array_key_exists($this->counter, $this->data)) {
                /* Data for regular placeholders is ended */
                throw new DataNotEnough(count($this->data), $this->counter);
            }
            $value = $this->data[$this->counter];
        }
        $this->counter++;
        $parser = new ParserPH($placeholder);
        $type = $parser->getType();
        $modifiers = $parser->getModifiers();
        $method = 'replacement'.strtoupper($type);
        return $this->$method($value, $modifiers);
    }
786913
protected static function cleanPre($matches)
    {
        if (is_array($matches))
        {
            $text = $matches[1] . $matches[2] . "</pre>";
        }
        else
        {
            $text = $matches;
        }

        $text = str_replace('<br />', '', $text);
        $text = str_replace('<p>', "\n", $text);
        $text = str_replace('</p>', '', $text);

        return $text;
    }
585712
private function _text(array $matches)
    {
        return \Mmi\App\FrontController::getInstance()->getView()->getHelper('text')->text($matches[1]);
    }
471866
private function getRegexp(array $patterns): string
    {
        $regexps = [];
        foreach ($patterns as $pattern) {
            // Escape namespace
            $regex = preg_quote(ltrim($pattern, '\\'));

            // Wildcards * and **
            $regex = strtr($regex, ['\\*\\*' => '.*?', '\\*' => '[^\\\\]*?']);

            // If this class does not end by a slash, anchor the end
            if ('\\' !== substr($regex, -1)) {
                $regex .= '$';
            }

            $regexps[] = '^'.$regex;
        }

        return sprintf('{%s}', implode('|', $regexps));
    }
1156999
protected function replaceCallback($matches)
    {
        if (!empty($matches['beforeSkip']) && !empty($matches['afterSkip'])) {
            return trim($matches[0], '{!} ');
        }
        // check: count quotes does not parity
        if (!NumericHelper::isParity(mb_substr_count($matches[0], '`', 'UTF-8'))) {
            return $matches[0];
        }
        $matches[0] = preg_replace_callback(
            '/
                \\s*(?P<sugar> (?!`)\*(?!`) | (?!`)\*\*(?!`) | (?!`)\/(?!`) | (?!`)\%(?!`) |
                \\s+(?!`)mod(?!`)\\s+ | (?!`)\+(?!`) | (?!`)\-(?!`) | (?!`)\|(?!`) | (?!`)\&(?!`) |
                (?!`)\^(?!`) | (?!`)\>\>(?!`) | (?!`)\<\<(?!`) |
                (?!`)\|\|(?!`) | (?!`)\&\&(?!`) | \\s+(?!`)' . $this->_getInlineConditionNames() . '(?!`)\\s+ |`\\s+\?\\s+|`\\s+\:\\s+)\\s*`
            /x',
            [$this, 'replaceSugar'],
            $matches[0]);
        // replace `=` tpl mnemonics
        $matches[0] = preg_replace('/`([\!\<\>]?)[\=]+`/', '`$1&#61;`', $matches[0]);
        // replace `text` to ““text””
        $matches[0] = preg_replace(['/=\\s*\`/', '/\`/'], ['=““', '””'], $matches[0]);
        // replacement of internal recursion on {{{...}}}
        $i = 0;
        $dataRecursive = [];
        $matches[0] = preg_replace_callback(
            '/\“\“(?:[^\“\”]++|(?R))*\”\”/iu',
            function ($value) use (&$dataRecursive, &$i) {
                $key = '{{{' . $i . '}}}';
                $value = current($value);
                $dataRecursive[$key] = $value;
                $i++;

                return $key;
            },
            $matches[0]
        );
        // Search params is variable of template
        $params = $this->_searchParams($matches[0], $dataRecursive);
        // Search of filters (modifiers)
        $filters = $this->_searchFilters($matches[0], $dataRecursive);
        $matches['name'] = trim($matches['name']);
        $params = Serialize::unserializeRecursive($params);
        // returns cache
        list($cacheKey, $cacheExpire, $cacheTags) = $this->calculateCacheParams($params);
        if (($resultCache = $this->getCacheContent($cacheKey)) !== false) {
            return $resultCache;
        }
        $filters = Serialize::unserializeRecursive($filters);
        $sanitize = $this->sanitize;
        if (isset($params['sanitize'])) {
            $sanitize = $params['sanitize'];
        } elseif(!empty($matches['sanitizeDisable'])) {
            $sanitize = self::SANITIZE_DISABLE;
        }

        // chunk
        if ($matches['type'] === '$') {
            $result = $this->getChunk($matches['name'], $params);
            // alias
        } elseif ($matches['type'] === '@@') {
            $result = Alias::getAlias("@{$matches['name']}");
            // placeholder
        } elseif ($matches['type'] === '+') {
            $result = $this->getPlaceholder($matches['name'], $sanitize);
            // constant
        } elseif ($matches['type'] === '++') {
            $result = $this->getConst($matches['name'], $sanitize);
            // extension
        } elseif ($matches['type'] === '#') {
            $result =
                $this->getExtension($matches['name'], $params, $sanitize);
            //  i18n
        } elseif ($matches['type'] === '%') {
            $result = $this->_calculateI18N(
                $matches['name'],
                Helper::getValue($params['placeholders'], []),
                Helper::getValue($params['locale']),
                Helper::getValue($params['category'])
            );
            // link
        } elseif ($matches['type'] === '~') {
            $result = $this->_calculateLink($matches['name'], $params);
            // snippet
        } elseif (empty($matches['type'])) {
            $result = $this->getSnippet($matches['name'], $params, $sanitize);
        } else {
            return $matches[0];
        }
        // make a filter
        if (!empty($filters)) {
            $result = $this->makeFilter($result, $filters);
        }
        if ($this->autoSerialize) {
            if (is_array($result) || (is_object($result) && !$result instanceof \Closure)) {
                $result = @serialize($result);
            }
        }
        if (!is_scalar($result) && !empty($result)) {
            throw new TemplateException('Wrong type is var: ' . Json::encode($result));
        }
        // sets a content to cache
        $this->setCacheContent(
            $cacheKey,
            $result,
            $cacheExpire,
            $cacheTags ?: []
        );

        return $result;
    }
1207629
private function tableClb($matches)
    {
        return $this->implementation->reprTable($this->connection, $this->prefix.$matches[1]);
    }
1195622
protected function replaceArgumentExpression($matches) {
		//count available matches
		//this indicates the type of expression to replace
		$total_matches = count($matches);
		$type = $subindex = null;
	
		//%{TYPE|CLASS@1}
		if ($total_matches == 2) {
			//check if there are arguments left
			if ($this->counter >= count($this->args))
				throw new \OutOfBoundsException("No arguments left for expression '{$matches[0]}'");

			return $this->castParameter($this->args[$this->counter++], $matches[1]);
		}
	
		switch ($total_matches) {
			/*
			 * Simple index
			 */
			case 5: //%{NUMBER@2[INDEX]@3?:TYPE@4}
				$type = substr($matches[4], 1);
			case 4: //%{NUMBER@2[INDEX]@3}
				$subindex = empty($matches[3]) ? null : substr($matches[3], 1, -1);
			case 3: //%{NUMBER@2}
				$index = intval($matches[2]);
					
				if (!array_key_exists($index, $this->args))
					throw new \InvalidArgumentException("No value found on index $index");
	
				if ($index == 0 && !is_null($subindex))
					return $this->getIndex($subindex, null, $type);
				
				return $this->getSubIndex($this->args[$index], $subindex, $type);
	
			/*
			 * Interval
			 */
			case 10: //%{NUMBER@5[LEFT@7?..RIGHT@8?]:TYPE@9}
				$type = substr($matches[9], 1);
			case 9: //%{NUMBER@5[LEFT@7?..RIGHT@8?]}
				$index = intval($matches[5]);
					
				if (!array_key_exists($index, $this->args))
					throw new \InvalidArgumentException("No value found on index $index");
					
				return $this->getSubRange($this->args[$index], $matches[7], $matches[8], $type);
		}
	}
1332912
public function convertLinkName(array $matches)
    {
        $replacedEmail = $this->linkNameConverter->convert(trim($matches[2]));

        return $matches[1] . $replacedEmail;
    }
334282
protected function replaceConfigExpression($matches) {
		$property = $matches[1];
		//check key existence
		if (!array_key_exists($property, $this->config))
			return '';
		//convert to string, if possible
		if (($str = $this->toString($this->config[$property])) === false)
			return '';
		return $str;
	}
40747
public function getNextStrpos($patterns)
    {
        $next = -1;
        $match = null;
        foreach ($patterns as $p) {
            $index = strpos($this->src, $p, $this->index);
            if ($index === false) {
                continue;
            }
            if ($next === -1 || $index < $next) {
                $next = $index;
                $match = $p;
            }
        }
        return array($next, $match);
    }
996327
protected function _processListItems_callback($matches) {
		$item = $matches[4];
		$leading_line =& $matches[1];
		$leading_space =& $matches[2];
		$marker_space = $matches[3];
		$tailing_blank_line =& $matches[5];

		if ($leading_line || $tailing_blank_line || 
			preg_match('/\n{2,}/', $item))
		{
			// Replace marker with the appropriate whitespace indentation
			$item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
			$item = $this->runBlockGamut($this->outdent($item)."\n");
		} else {
			// Recursion for sub-lists:
			$item = $this->doLists($this->outdent($item));
			$item = $this->formParagraphs($item, false);
		}

		return "<li>" . $item . "</li>\n";
	}
150297
public static function replacePlaceholders($string, array $replacements) {
    // Make sure the replacements don't have any unneeded newlines.
    $replacements = array_map('trim', $replacements);
    $string = strtr($string, $replacements);
    // Remove noise caused by empty placeholders.
    $lines = explode("\n", $string);
    foreach ($lines as $index => $line) {
      // Remove leading punctuation, excess whitespace.
      $line = trim(preg_replace('/^[-,]+/', '', $line, 1));
      $line = preg_replace('/\s\s+/', ' ', $line);
      $lines[$index] = $line;
    }
    // Remove empty lines.
    $lines = array_filter($lines);

    return implode("\n", $lines);
  }
954184
protected function doReplaceNameInExpression($matches)
    {
        $key = $matches[0];
        list($column, $realColumnName) = $this->getColumnFromName($key);
        if ($column instanceof ColumnMap) {
            $this->replacedColumns[] = $column;
            $this->foundMatch = true;

            return $realColumnName;
        } else {
            return $key;
        }
    }
1318504
protected function literal(array $matches)
    {
        // hash from matches
        $hash = '[!' . __FUNCTION__ . '::read(' . \crc32($matches[1]) . ')!]';

        // save hash and value to literals array
        $this->literals[$hash] = $matches[1];

        // return hash value for replace
        return $hash;
    }
875282
public function compile($matches)
    {
        $variable = rtrim($matches[2], ';');
        
        return $this->compiler->wrap(
            $this->compiler->stringDotsToArrayKeys($variable)
        );
    }
131072
public function setMatches($matches)
    {
        foreach ($matches as $key => $dtoData) {
            $this->matches[$key] = new MatchReferenceDto($dtoData);
        }
    
        return $this;
    }
175618
protected function replacePropertyExpression($matches) {
		//count available matches
		//this indicates the type of expression to replace
		$total_matches = count($matches);
		$type = $subindex = null;
	
		switch ($total_matches) {
			/*
			 * Property
			 */
			case 4: //#{PROPERTY@1[INDEX]@2?:TYPE@3}
				$type = substr($matches[3], 1);
			case 3: //#{PROPERTY@1[INDEX]@2}
				$subindex = empty($matches[2]) ? null : substr($matches[2], 1, -1);
			case 2: //#{PROPERTY@1}
				$key = $matches[1];

				//obtain type from annotation (when possible)
				if (is_null($type) && $this->wrappedArg instanceof ObjectArgumentWrapper) {
					if ($this->wrappedArg->getClassProfile()->isEntity()) {
						$property = $this->wrappedArg->getClassProfile()->getProperty($key);
						$type = $property->getType();
					}
				}
	
				return $this->getIndex($key, $subindex, $type);
				break;
	
			/*
			 * Interval
			 */
			case 9: //#{PROPERTY@4[LEFT_INDEX@6..RIGHT_INDEX@7]:TYPE@8}
				$type = substr($matches[8], 1);
			case 8: //#{PROPERTY@4[LEFT_INDEX@6..RIGHT_INDEX@7]}
				$key = $matches[4];
					
				//obtain type from annotation (when possible)
				if (is_null($type) && $this->wrappedArg instanceof ObjectArgumentWrapper) {
					if ($this->wrappedArg->getClassProfile()->isEntity()) {
						$property = $this->wrappedArg->getClassProfile()->getProperty($key);
						$type = $property->getType();
					}
				}
					
				return $this->getRange($key, $matches[6], $matches[7], $type);
				break;
		}
	}