"", self::MATHML_NAMESPACE => "math", self::SVG_NAMESPACE => "svg", self::XLINK_NAMESPACE => "xlink", self::XML_NAMESPACE => "xml", self::XMLNS_NAMESPACE => "xmlns", ]; public static function parse(string $data, ?string $encodingOrContentType = null, ?\DOMDocument $document = null, ?\DOMElement $fragmentContext = null, ?int $fragmentQuirks = null, ?Config $config = null): Output { // Initialize the various classes needed for parsing $document = $document ?? new \DOMDocument; $config = $config ?? new Config; $errorHandler = $config->errorCollection ? new ParseError : null; $decoder = new Data($data, $encodingOrContentType, $errorHandler, $config->encodingFallback); $stack = new OpenElementsStack($fragmentContext); $tokenizer = new Tokenizer($decoder, $stack, $errorHandler); $tokenList = $tokenizer->tokenize(); $treeBuilder = new TreeBuilder($document, $decoder, $tokenizer, $tokenList, $errorHandler, $stack, new TemplateInsertionModesStack, $fragmentContext, $fragmentQuirks); $treeBuilder->constructTree(); // prepare the output $out = new Output; $out->document = $document; $out->encoding = $decoder->encoding; $out->quirksMode = $treeBuilder->quirksMode; if ($errorHandler) { $out->errors = $errorHandler->errors; } return $out; } public static function parseFragment(\DOMElement $fragmentContext, ?int $fragmentQuirks, string $data, ?string $encodingOrContentType = null, ?\DOMDocument $document = null, ?Config $config = null): \DOMDocumentFragment { // Create the requisite parsing context if none was supplied $document = $document ?? new \DOMDocument; // parse the fragment into the temporary document self::parse($data, $encodingOrContentType, $document, $fragmentContext, $fragmentQuirks, $config); // extract the nodes from the temp document into a fragment $fragment = $fragmentContext->ownerDocument->createDocumentFragment(); foreach ($document->documentElement->childNodes as $node) { $node = $fragment->ownerDocument->importNode($node, true); $fragment->appendChild($node); } return $fragment; } public static function fetchFile(string $file, ?string $encodingOrContentType = null): ?array { $f = fopen($file, "r"); if (!$f) { return null; } $data = stream_get_contents($f); $encoding = Charset::fromCharset((string) $encodingOrContentType) ?? Charset::fromTransport((string) $encodingOrContentType); if (!$encoding) { $meta = stream_get_meta_data($f); if ($meta['wrapper_type'] === "http") { // Try to find a Content-Type header-field foreach ($meta['wrapper_data'] as $h) { $h = explode(":", $h, 2); if (count($h) === 2) { if (preg_match("/^\s*Content-Type\s*$/i", $h[0])) { // Try to get an encoding from it $encoding = Charset::fromTransport($h[1]); break; } } } } } return [$data, $encoding]; } }