Parses an HTML fragment.
@param $text | HTML text to parse
@param $context String name of context element to pretend parsing is in.
@param $builder | Custom builder implementation
@return DOMDocument|DOMNodeList Parsed HTML as DOMDocument
777963
static public function parseFragment($text, $context = null, $builder = null) {
        $tokenizer = new HTML5_Tokenizer($text, $builder);
        $tokenizer->parseFragment($context);
        return $tokenizer->save();
    }
492527
protected function wrapHTML($html, $config, $context)
    {
        $def = $config->getDefinition('HTML');
        $ret = '';

        if (!empty($def->doctype->dtdPublic) || !empty($def->doctype->dtdSystem)) {
            $ret .= '<!DOCTYPE html ';
            if (!empty($def->doctype->dtdPublic)) {
                $ret .= 'PUBLIC "' . $def->doctype->dtdPublic . '" ';
            }
            if (!empty($def->doctype->dtdSystem)) {
                $ret .= '"' . $def->doctype->dtdSystem . '" ';
            }
            $ret .= '>';
        }

        $ret .= '<html><head>';
        $ret .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
        // No protection if $html contains a stray </div>!
        $ret .= '</head><body>' . $html . '</body></html>';
        return $ret;
    }
695945
public function parse_recursive(DOMElement $context = null, $depth = 0) {
		$mfs = array();
		$mfElements = $this->getRootMF($context);

		foreach ($mfElements as $node) {
			$is_backcompat = !$this->hasRootMf2($node);

			if ($this->convertClassic && $is_backcompat) {
				$this->backcompat($node);
			}

			$recurse = $this->parse_recursive($node, $depth + 1);

			// set bool flag for nested mf
			$has_nested_mf = ($recurse);

			// parse for root mf
			$result = $this->parseH($node, $is_backcompat, $has_nested_mf);

			// TODO: Determine if clearing this is required?
			$this->elementPrefixParsed($node, 'h');
			$this->elementPrefixParsed($node, 'p');
			$this->elementPrefixParsed($node, 'u');
			$this->elementPrefixParsed($node, 'dt');
			$this->elementPrefixParsed($node, 'e');

			// parseH returned a parsed result
			if ($result) {

				// merge recursive results into current results
				if ($recurse) {
					$result = array_merge_recursive($result, $recurse);
				}

				// currently a nested mf; check if node is an mf property of parent
				if ($depth > 0) {
					$temp_properties = nestedMfPropertyNamesFromElement($node);

					// properties found; set up parsed result in 'properties'
					if (!empty($temp_properties)) {

						foreach ($temp_properties as $property => $prefixes) {
							// Note: handling microformat nesting under multiple conflicting prefixes is not currently specified by the mf2 parsing spec.
							$prefixSpecificResult = $result;
							if (in_array('p-', $prefixes)) {
								$prefixSpecificResult['value'] = (!is_array($prefixSpecificResult['properties']) || empty($prefixSpecificResult['properties']['name'][0])) ? $this->parseP($node) : $prefixSpecificResult['properties']['name'][0];
							} elseif (in_array('e-', $prefixes)) {
								$eParsedResult = $this->parseE($node);
								$prefixSpecificResult['html'] = $eParsedResult['html'];
								$prefixSpecificResult['value'] = $eParsedResult['value'];
							} elseif (in_array('u-', $prefixes)) {
								$prefixSpecificResult['value'] = (!is_array($result['properties']) || empty($result['properties']['url'])) ? $this->parseU($node) : reset($result['properties']['url']);
							} elseif (in_array('dt-', $prefixes)) {
								$parsed_property = $this->parseDT($node);
								$prefixSpecificResult['value'] = ($parsed_property) ? $parsed_property : '';
							}

							$mfs['properties'][$property][] = $prefixSpecificResult;
						}

					// otherwise, set up in 'children'
					} else {
						$mfs['children'][] = $result;
					}
				// otherwise, top-level mf
				} else {
					$mfs[] = $result;
				}
			}
		}

		return $mfs;
	}
686017
private static function ParseStructuredValue($Text, $Key)
	{
		$Text = array_map('trim', explode(';', $Text));

		$Result = array();
		$Ctr = 0;

		foreach (self::$Spec_StructuredElements[$Key] as $Index => $StructurePart)
		{
			$Result[$StructurePart] = isset($Text[$Index]) ? $Text[$Index] : null;
		}
		return $Result;
	}
142999
protected static function rawblock(&$token, &$context) {
        $inner = $token[Token::POS_INNERTAG];
        trim($inner);

        // skip parse when inside raw block
        if ($context['rawblock'] && !(($token[Token::POS_BEGINRAW] === '{{') && ($token[Token::POS_OP] === '/') && ($context['rawblock'] === $inner))) {
            return true;
        }

        $token[Token::POS_INNERTAG] = $inner;

        // Handle raw block
        if ($token[Token::POS_BEGINRAW] === '{{') {
            if ($token[Token::POS_ENDRAW] !== '}}') {
                $context['error'][] = 'Bad token ' . Token::toString($token) . ' ! Do you mean ' . Token::toString($token, array(Token::POS_ENDRAW => '}}')) . ' ?';
            }
            if ($context['rawblock']) {
                Parser::setDelimiter($context);
                $context['rawblock'] = false;
            } else {
                if ($token[Token::POS_OP]) {
                    $context['error'][] = "Wrong raw block begin with " . Token::toString($token) . ' ! Remove "' . $token[Token::POS_OP] . '" to fix this issue.';
                }
                $context['rawblock'] = $token[Token::POS_INNERTAG];
                Parser::setDelimiter($context);
                $token[Token::POS_OP] = '#';
            }
            $token[Token::POS_ENDRAW] = '}}';
        }
    }
844255
protected function getParser($context = null)
    {
        $parser = $this->getComponent('parser');

        $parser->registeredVars['context'] = $context;

        return $parser;
    }
1307084
public function parse($text)
	{
		// Reset the parser and save the uid
		$this->reset($text);
		$uid = $this->uid;

		// Do the heavy lifting
		$this->executePluginParsers();
		$this->processTags();

		// Finalize the document
		$this->finalizeOutput();

		// Check the uid in case a plugin or a filter reset the parser mid-execution
		if ($this->uid !== $uid)
		{
			throw new RuntimeException('The parser has been reset during execution');
		}

		// Log a warning if the fixing cost limit was exceeded
		if ($this->currentFixingCost > $this->maxFixingCost)
		{
			$this->logger->warn('Fixing cost limit exceeded');
		}

		return $this->output;
	}
548625
public function loadGrammar(string $text): Grammar
    {
        $this->symbols = [];
        $this->inline = [];
        $this->regexpMap = [];
        $this->defines = [];
        $this->whitespaces = [];
        $this->modifiers = null;

        try {
            /** @var Rule[] $rules */
            $rules = $this->parser->parse($text, $this->actions)->made();

            /** @var int[] $subject_rules_count */
            $subject_rules_count = [];
            /** @var int[] $inline_ref_count */
            $inline_ref_count = [];
            /** @var Rule[] $inline_ref_rule */
            $inline_ref_rule = [];

            $non_terminal_is_hidden = [];
            $hidden_non_terminals = [];

            foreach ($rules as $rule) {
                $subject = $rule->getSubject();
                $subject_name = $subject->getName();
                $subject_hidden = $subject->isHidden();

                // RegExp tokens cannot be non-terminals in the same time
                // since there is no anonymous RegExp terminals
                if (isset($this->regexpMap[$subject_name])) {
                    throw new GrammarException(
                        "Symbol `$subject_name` defined as non-terminal and as regexp terminal in the same time"
                    );
                }

                if (isset($non_terminal_is_hidden[$subject_name])) {
                    if ($subject_hidden !== $non_terminal_is_hidden[$subject_name]) {
                        throw new GrammarException(
                            "Symbol `$subject_name` defined both as hidden and as visible"
                        );
                    }
                } else {
                    $non_terminal_is_hidden[$subject_name] = $subject_hidden;
                }

                $subject_rules_count[$subject_name] = ($subject_rules_count[$subject_name] ?? 0) + 1;

                if ($subject_hidden) {
                    $hidden_non_terminals[$subject_name] = true;
                }

                foreach ($rule->getDefinition() as $symbol) {
                    $name = $symbol->getName();
                    if (isset($this->inline[$name])) {
                        $inline_ref_count[$name] = ($inline_ref_count[$name] ?? 0) + 1;

                        // it is needed in case of the only reference,
                        // so array of an subject is not needed
                        $inline_ref_rule[$name] = $rule;
                    }
                }
            }

            foreach ($hidden_non_terminals as $name => $_) {
                if (isset($this->symbols[$name][false])) {
                    $this->symbols[$name][false]->setIsHidden(true);
                }
            }

            // Convert non-terminals defined only once with inline tokens
            // `Subject: "inline"`
            // into fixed terminals
            $fixed = [];
            foreach ($inline_ref_count as $inline_token => $ref_count) {
                if (1 !== $ref_count) {
                    continue;
                }

                $rule = $inline_ref_rule[$inline_token];
                if (null === $rule->getTag() && 1 === count($rule->getDefinition())) {
                    $subject = $rule->getSubject();
                    $name = $subject->getName();

                    if (1 !== $subject_rules_count[$name]) {
                        continue;
                    }

                    // remove rule
                    $key = array_search($rule, $rules, true);
                    if (false !== $key) {
                        unset($rules[$key]);
                    }

                    // remove inline
                    unset($this->inline[$inline_token]);

                    // make terminal
                    $subject->setIsTerminal(true);
                    if (isset($this->symbols[$name][!$subject->isHidden()])) {
                        $this->symbols[$name][!$subject->isHidden()]->setIsTerminal(true);
                    }

                    $fixed[$name] = $inline_token;
                }
            }

            return new Grammar(
                $rules,
                $this->inline,
                $fixed,
                $this->regexpMap,
                $this->whitespaces,
                $this->defines,
                $this->modifiers ?? ''
            );
        } catch (UnknownCharacterException | UnexpectedInputAfterEndException | UnexpectedTokenException $e) {
            throw new GrammarException(
                'Cannot parse grammar: ' . $e->getMessage() . ' at offset ' . $e->getOffset(),
                0,
                $e
            );
        } catch (AbortedException $e) {
            for ($inner = $e; $inner; $inner = $inner->getPrevious()) {
                if ($inner instanceof GrammarException || $inner instanceof InternalException) {
                    throw $inner;
                }
            }
            throw new InternalException('Failure while parsing your grammar text', 0, $e);
        } finally {
            $this->symbols = null;
            $this->inline = null;
            $this->regexpMap = null;
            $this->defines = null;
            $this->whitespaces = null;
            $this->modifiers = null;
        }
    }
804155
protected function _parseTags(&$text, TemplateInterface $template)
    {
        $tags = '';

        $matches = array();
        if(preg_match_all('#<meta\ content="([^"]+)"(.*)\/>#siU', $text, $matches))
        {
            foreach($matches[1] as $key => $match)
            {
                //Set required attributes
                $attribs = array(
                    'content' => $match
                );

                $attribs = array_merge($this->parseAttributes( $matches[2][$key]), $attribs);
                $tags .= $this->_renderTag($attribs, null, $template);
            }

            $text = str_replace($matches[0], '', $text);
        }

        return $tags;
    }
1340746
function parse($html)
		{
			$dom = new \DOMDocument();
			libxml_use_internal_errors(true);
			$dom->loadHTML($html);
			$xpath = new \DOMXPath($dom);
			
			// Load resources for tag actions
			$this->ignoreElements = new ResourceProvider("html_tag_actions/ignore.lst");
			$this->linkElements = new ResourceProvider("html_tag_actions/link.lst");
			$this->bodyElements = new ResourceProvider("html_tag_actions/body.lst");
			$this->inlineElements = new ResourceProvider("html_tag_actions/inline.lst");
			
			/*	
			 *  1st retrieve page title
			 *  With this technique: only process the entire document here 
			 *  as meta is excluded as 'content' and only required for initial title.
			 */

			// Extract title from DOM
			$body = $xpath->query('/')->item(0);
			$titleItem = $xpath->query('//title')->item(0);
			
			if(isset($titleItem))
			{
				$title = $titleItem->textContent;
			}
			$body = $xpath->query('//body')->item(0);
			
			// Try to extract title from OG meta
			foreach ($xpath->query("//meta[@property='og:title']") as $el) 
			{
				$title = $el->getAttribute("content");
			}
			
			$this->recurse($body);
			$Article = new Article();
			if(isset($title))
			{
				$Article->title = $title;
			}
			$Article->textBlocks = $this->textBlocks;
			return $Article;
		}
731116
private function parseTagBlock(string $tags, Types\Context $context): array
    {
        $tags = $this->filterTagBlock($tags);
        if (!$tags) {
            return [];
        }

        $result = $this->splitTagBlockIntoTagLines($tags);
        foreach ($result as $key => $tagLine) {
            $result[$key] = $this->tagFactory->create(trim($tagLine), $context);
        }

        return $result;
    }
558449
public static function process($content, $context = null, $paragraph = false)
    {
        if (!isset(Markdown::$flavors['api-latex'])) {
            Markdown::$flavors['api-latex'] = new static;
        }

        if (is_string($context)) {
            $context = static::$renderer->apiContext->getType($context);
        }
        Markdown::$flavors['api-latex']->renderingContext = $context;

        if ($paragraph) {
            return Markdown::processParagraph($content, 'api-latex');
        } else {
            return Markdown::process($content, 'api-latex');
        }
    }
1201576
public function parse(Token $token)
    {
        $lineno = $token->getLine();

        [$object, $layout, $context] = $this->parseArguments($token);

        return new TwigNodeRender($object, $layout, $context, $lineno, $this->getTag());
    }
284068
public function parseBlock(Text $content, Container $target)
    {
        $content->handle(
            '{
                (?:                 # Ensure blank line before (or beginning of subject)
                    \A\s*\n?|
                    \n\s*\n
                )
                [ ]{4}              # four leading spaces
                .+
                (?:                 # optionally more spaces
                    (?:             # blank lines in between are okay
                        \n[ ]*
                    )*
                    \n
                    [ ]{4}
                    .+
                )*
                $
            }mx',
            function (Text $code) use ($target) {
                // Remove leading blank lines
                $code->replace('/^(\s*\n)*/', '');

                // Remove indent
                $code->replace('/^[ ]{1,4}/m', '');
                $code->append("\n");

                $target->addChild(new CodeBlock($code));
            },
            function(Text $part) use ($target) {
                $this->next->parseBlock($part, $target);
            }
        );
    }
1272664
public function parse(string $text) : string
    {
        if ($text === '')
            throw new ParseException($this, $text, 0, self::NO_EMPTY);
        return $text;
    }
132487
public function paragraph(string $text = null): Paragraph
    {
        $paragraph = Paragraph::factory();
        if ($text !== null) {
            $paragraph->text($text);
        }

        /** @var ContainerElement $this */
        return $this->addElement($paragraph);
    }
986269
public function parse($str, $context = null)
    {
        $this->lexer->setInput($str);
        $this->context = $context;

        $rs = $this->parseInternal();

        if (null !== $this->lexer->next) {
            $this->syntaxError('end of input');
        }

        return $rs;
    }