public function __construct(SyntaxInterface $syntax = null) { $this->syntax = $syntax ?: new Syntax(); $this->shortcodeRegex = RegexBuilderUtility::buildShortcodeRegex($this->syntax); $this->singleShortcodeRegex = RegexBuilderUtility::buildSingleShortcodeRegex($this->syntax); $this->parametersRegex = RegexBuilderUtility::buildParametersRegex($this->syntax); }
private function shortcode(array &$names) { $name = null; $offset = null; $setName = function (array $token) use(&$name) { $name = $token[1]; }; $setOffset = function (array $token) use(&$offset) { $offset = $token[2]; }; if (!$this->match(self::TOKEN_OPEN, $setOffset, true)) { return false; } if (!$this->match(self::TOKEN_STRING, $setName, false)) { return false; } if ($this->lookahead(self::TOKEN_STRING, null)) { return false; } if (!preg_match_all('~^' . RegexBuilderUtility::buildNameRegex() . '$~us', $name, $matches)) { return false; } $this->match(self::TOKEN_WS); if (false === ($bbCode = $this->bbCode())) { return false; } if (false === ($parameters = $this->parameters())) { return false; } // self-closing if ($this->match(self::TOKEN_MARKER, null, true)) { if (!$this->match(self::TOKEN_CLOSE)) { return false; } return array($this->getObject($name, $parameters, $bbCode, $offset, null, $this->getBacktrack())); } // just-closed or with-content if (!$this->match(self::TOKEN_CLOSE)) { return false; } $this->beginBacktrack(); $names[] = $name; list($content, $shortcodes, $closingName) = $this->content($names); if (null !== $closingName && $closingName !== $name) { array_pop($names); array_pop($this->backtracks); array_pop($this->backtracks); return $closingName; } if (false === $content || $closingName !== $name) { $this->backtrack(false); $text = $this->backtrack(false); return array_merge(array($this->getObject($name, $parameters, $bbCode, $offset, null, $text)), $shortcodes); } $content = $this->getBacktrack(); if (!$this->close($names)) { return false; } return array($this->getObject($name, $parameters, $bbCode, $offset, $content, $this->getBacktrack())); }
private function parseSingle($text, $offset) { preg_match($this->singleShortcodeRegex, $text, $matches, PREG_OFFSET_CAPTURE); $name = $matches['name'][0]; if (!preg_match('~^' . RegexBuilderUtility::buildNameRegex() . '$~us', $name)) { return null; } $parameters = isset($matches['parameters'][0]) ? $this->parseParameters($matches['parameters'][0]) : array(); $bbCode = isset($matches['bbCode'][0]) && $matches['bbCode'][1] !== -1 ? $this->extractValue($matches['bbCode'][0]) : null; $content = isset($matches['content'][0]) && $matches['content'][1] !== -1 ? $matches['content'][0] : null; return new ParsedShortcode(new Shortcode($name, $parameters, $content, $bbCode), $text, $offset); }
/** * @param string $text * * @return ParsedShortcode[] */ public function parse($text) { $names = $this->names ? implode('|', array_map('preg_quote', $this->names)) : RegexBuilderUtility::buildNameRegex(); $regex = str_replace('<NAMES>', $names, static::$shortcodeRegex); preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE); $shortcodes = array(); $count = count($matches[0]); for ($i = 0; $i < $count; $i++) { $name = $matches[2][$i][0]; $parameters = static::parseParameters($matches[3][$i][0]); $content = $matches[5][$i][0] ?: null; $match = $matches[0][$i][0]; $offset = mb_strlen(substr($text, 0, $matches[0][$i][1]), 'utf-8'); $shortcode = new Shortcode($name, $parameters, $content, null); $shortcodes[] = new ParsedShortcode($shortcode, $match, $offset); } return $shortcodes; }