Wraps a set of HTML nodes in an HTML4-document

@param  string $nodes   One or more HTML-nodes, as a string
@param  string $charset Charset to specify in meta tag
@param  string $parser  Validator parser used
@return string
977780
protected function wrapInHtml4Document($nodes, $charset = null, $parser = null) {
        if ($parser === Validator::PARSER_HTML4TR) {
            $doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
        } else {
            $doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
        }

        $charset = strtolower($charset ?: Validator::CHARSET_UTF_8);

        $document  = $doctype . PHP_EOL;
        $document .= '<html><head>' . PHP_EOL;
        $document .= '<meta http-equiv="Content-Type" content="text/html; charset=' . $charset . '">' . PHP_EOL;
        $document .= '<title>Validation document</title>' . PHP_EOL;
        $document .= '</head><body>' . $nodes . '</body></html>';

        return $document;
    }
559835
public function setCharset($charset)
    {
        $prev = $this->charset;

        $charset = strtoupper($charset);
        $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset;

        $this->charset = $charset;

        return $prev;
    }
1079791
private function parseElementNodes($children, $parentName = null)
    {
        $result = [];

        foreach ($children as $child) {
            $prefix = $child->prefix ?: null;
            $oname  = $this->normalizeKey($child->nodeName);
            $name   = $this->prefixKey($oname, $prefix);

            if (isset($result[$name])) {
                $this->parseSetResultNodes($child, $name, $result);
                continue;
            }

            $this->parseUnsetResultNodes($child, $name, $oname, $parentName, $result, $prefix);
        }

        return $result;
    }
918385
protected function convertHtmlToText(\DOMNodeList $nodes)
    {
        $text = "";

        /** @var \DOMElement $node */
        foreach ($nodes as $node) {
            $lineBreaksBefore = 0;
            $lineBreaksAfter = 0;
            $lineCharBefore = "";
            $lineCharAfter = "";
            $prefix = "";
            $suffix = "";

            if (in_array($node->nodeName, ["h1", "h2", "h3", "h4", "h5", "h6", "h"])) {
                $lineCharAfter = "=";
                $lineBreaksAfter = 2;
            } elseif (in_array($node->nodeName, ["p", "td"])) {
                $lineBreaksAfter = 2;
            } elseif (in_array($node->nodeName, ["div"])) {
                $lineBreaksAfter = 1;
            }

            if ($node->nodeName === "h1") {
                $lineCharBefore = "*";
                $lineCharAfter = "*";
            } elseif ($node->nodeName === "h2") {
                $lineCharBefore = "=";
            }

            if ($node->nodeName === '#text') {
                $textContent = html_entity_decode($node->textContent, ENT_COMPAT | ENT_HTML401, $this->getCharset());

                // Replace tabs (used to mark links below) and other control characters
                $textContent = preg_replace("/[\r\n\f\v\t]+/", "", $textContent);

                if ($textContent !== "") {
                    $text .= $textContent;
                }
            } elseif ($node->nodeName === 'a') {
                $href = "";
                if ($node->attributes !== null) {
                    $hrefAttribute = $node->attributes->getNamedItem("href");
                    if ($hrefAttribute !== null) {
                        $href = (string)$hrefAttribute->nodeValue;
                    }
                }
                if ($href !== "") {
                    $suffix = " (\t" . $href . "\t)";
                }
            } elseif ($node->nodeName === 'b' || $node->nodeName === 'strong') {
                $prefix = "*";
                $suffix = "*";
            } elseif ($node->nodeName === 'hr') {
                $text .= str_repeat('-', 75) . "\n\n";
            }

            if ($node->hasChildNodes()) {
                $text .= str_repeat("\n", $lineBreaksBefore);

                $addText = $this->convertHtmlToText($node->childNodes);

                $text .= $prefix;

                $text .= $lineCharBefore ? str_repeat($lineCharBefore, 75) . "\n" : "";
                $text .= $addText;
                $text .= $lineCharAfter ? "\n" . str_repeat($lineCharAfter, 75) . "\n" : "";

                $text .= $suffix;

                $text .= str_repeat("\n", $lineBreaksAfter);
            }
        }

        // Remove unnecessary white spaces at he beginning/end of lines
        $text = preg_replace("/(?:^[ \t\f]+([^ \t\f])|([^ \t\f])[ \t\f]+$)/m", "\\1\\2", $text);

        // Replace multiple line-breaks
        $text = preg_replace("/[\r\n]{2,}/", "\n\n", $text);

        return $text;
    }
123059
private function xmlCharacterData($parser, $data)
    {
        $count = $this->xmlCount - 1;
        if (!empty($this->xmlCData[$count])) {
            $this->xmlCData[$count] .= $data;
        } else {
            $this->xmlCData[$count] = $data;
        }
    }
771354
public function setCharset($charset)
    {
        $this->charset = $charset;
        $this->setContentType($this->getContentType()); // update charset which is set on content-type

        return $this;
    }
503731
public function parse(array $tokens)
    {
        $parser = new Parser($this->symbolContainer);

        if ($this->customGrammarChecker !== null) {
            $parser->setCustomGrammarChecker($this->customGrammarChecker);
        }

        $rootNode = $parser->parse($tokens);

        return $rootNode;
    }
619350
public function setCharacterSet($charset)
    {
        $this->charset = $charset;
        $this->charReader = null;
        $this->mapType = 0;
    }
152420
public static function parse_attrib_string($str)
    {
        $attrib = array();
        $html   = '<html>'
            . '<head><meta http-equiv="Content-Type" content="text/html; charset=' . RCUBE_CHARSET . '" /></head>'
            . '<body><div ' . rtrim($str, '/ ') . ' /></body>'
            . '</html>';

        $document = new DOMDocument('1.0', RCUBE_CHARSET);
        @$document->loadHTML($html);

        if ($node = $document->getElementsByTagName('div')->item(0)) {
            foreach ($node->attributes as $name => $attr) {
                $attrib[strtolower($name)] = $attr->nodeValue;
            }
        }

        return $attrib;
    }
41665
function parse() {
    $this->output = '';
    # drop tags
    $this->parser->html = preg_replace('#<('.implode('|', $this->drop).')[^>]*>.*</\\1>#sU', '', $this->parser->html);
    while ($this->parser->nextNode()) {
      switch ($this->parser->nodeType) {
        case 'doctype':
          break;
        case 'pi':
        case 'comment':
          if ($this->keepHTML) {
            $this->flushLinebreaks();
            $this->out($this->parser->node);
            $this->setLineBreaks(2);
          }
          # else drop
          break;
        case 'text':
          $this->handleText();
          break;
        case 'tag':
          if (in_array($this->parser->tagName, $this->ignore)) {
            break;
          }
          if ($this->parser->isStartTag) {
            $this->flushLinebreaks();
          }
          if ($this->skipConversion) {
            $this->isMarkdownable(); # update notConverted
            $this->handleTagToText();
            continue;
          }
          if (!$this->parser->keepWhitespace && $this->parser->isBlockElement && $this->parser->isStartTag) {
            $this->parser->html = ltrim($this->parser->html);
          }
          if ($this->isMarkdownable()) {
            if ($this->parser->isBlockElement && $this->parser->isStartTag && !$this->lastWasBlockTag && !empty($this->output)) {
              if (!empty($this->buffer)) {
                $str =& $this->buffer[count($this->buffer) -1];
              } else {
                $str =& $this->output;
              }
              if (substr($str, -strlen($this->indent)-1) != "\n".$this->indent) {
                $str .= "\n".$this->indent;
              }
            }
            $func = 'handleTag_'.$this->parser->tagName;
            $this->$func();
            if ($this->linksAfterEachParagraph && $this->parser->isBlockElement && !$this->parser->isStartTag && empty($this->parser->openTags)) {
              $this->flushStacked();
            }
            if (!$this->parser->isStartTag) {
              $this->lastClosedTag = $this->parser->tagName;
            }
          } else {
            $this->handleTagToText();
            $this->lastClosedTag = '';
          }
          break;
        default:
          trigger_error('invalid node type', E_USER_ERROR);
          break;
      }
      $this->lastWasBlockTag = $this->parser->nodeType == 'tag' && $this->parser->isStartTag && $this->parser->isBlockElement;
    }
    if (!empty($this->buffer)) {
      trigger_error('buffer was not flushed, this is a bug. please report!', E_USER_WARNING);
      while (!empty($this->buffer)) {
        $this->out($this->unbuffer());
      }
    }
    ### cleanup
    $this->output = rtrim(str_replace('&amp;', '&', str_replace('&lt;', '<', str_replace('&gt;', '>', $this->output))));
    # end parsing, flush stacked tags
    $this->flushStacked();
    $this->stack = array();
  }
274764
private function prepareNodesTree(
        $nodes,
        $webspaceKey,
        $languageCode,
        $complete = true,
        $excludeGhosts = false,
        $maxDepth = 1,
        $currentDepth = 0
    ) {
        ++$currentDepth;

        $results = [];
        foreach ($nodes as $node) {
            $result = $this->prepareNode($node, $webspaceKey, $languageCode, 1, $complete, $excludeGhosts);
            if (null !== $maxDepth &&
                $currentDepth < $maxDepth &&
                $node->getHasChildren() &&
                null != $node->getChildren()
            ) {
                $result['_embedded']['nodes'] = $this->prepareNodesTree(
                    $node->getChildren(),
                    $webspaceKey,
                    $languageCode,
                    $complete,
                    $excludeGhosts,
                    $maxDepth,
                    $currentDepth
                );
            }
            $results[] = $result;
        }

        return $results;
    }
621980
public function parse(string $html) : TokenCollection
    {
        self::$allHtml = $html;
        $tokens = new TokenCollection();
        $remainingHtml = trim($html);
        while (mb_strlen($remainingHtml) > 0) {
            $token = TokenFactory::buildFromHtml(
                $remainingHtml,
                null,
                $this->throwOnError
            );
            if (!$token instanceof Token) {
                // Error has occurred, so we stop.
                break;
            }

            $remainingHtml = $token->parse($remainingHtml);
            $tokens[] = $token;
        }

        return $tokens;
    }
503266
public static function htmlentities($str = '', $encodeTags = true, $isXml = false, $charset = null)
    {
        $debug = \bdk\Debug::getInstance();
        $dbWas = $debug->setCfg('collect', false);
        $debug->groupCollapsed(__FUNCTION__);
        $return = '';
        $charsetsTry = array('UTF-8','ISO-8859-1');
        $debug->log('charset', $charset);
        if (is_null($charset) && extension_loaded('mbstring')) {
            $charset = mb_detect_encoding($str, mb_detect_order(), true);
            $debug->log('charset detected', $charset);
        }
        if ($charset) {
            $charset = self::getCharset($charset);
            if ($charset == 'UTF-8' && !Str::isUtf8($str)) {
                $charset = null;
            }
        }
        if ($charset) {
            #$debug->log('will try charset '.$charset.' first');
            array_unshift($charsetsTry, $charset);
            $charsetsTry = array_unique($charsetsTry);
        }
        $debug->log('charsetsTry', implode(', ', $charsetsTry));
        $return = self::htmlentitiesApply($str, $encodeTags, $isXml, $charsetsTry);
        #$debug->log('return', $return);
        $debug->groupEnd();
        $debug->setCfg('collect', $dbWas);
        return $return;
    }
866388
public function serializeNodes(array $nodes, $language, TokenInterface $token)
    {
        $return = [];

        foreach ($nodes as $node) {
            $nodeData = $this->serializeNode($node, $language, $token);

            if ($nodeData) {
                $return[] = $nodeData;
            }
        }

        return $return;
    }
1269721
public function charXML($parser, $data) {
		if(array_key_exists($this->xml_depth, $this->xmlobj)) {
			$this->xmlobj[$this->xml_depth]->data .= $data;
		}
	}
1161525
public function validateDocument($document, $charset = null) {
        $document = (string) $document;
        $charset  = $charset ?: $this->defaultCharset;
        $headers  = [
            'Content-Type' => $this->getContentTypeString(
                $this->getMimeTypeForParser($this->parser),
                $charset
            ),
        ];

        $response = $this->httpClient->request('POST', '', [
            'body' => $document,
            'headers' => $headers,
            'query' => [
                'out' => 'json',
                'parser' => $this->parser
            ],
        ]);

        try {
            $response = new Response($response);
        } catch (RequestException $e) {
            throw new ServerException($e->getMessage());
        }

        return $response;
    }
22181
public function setCharset( string $charset = 'UTF8' ) : MySQL
   {

      if ( ! $this->_supportedAttributes->get( 'charset' )->validateValue( $charset ) )
      {
         throw new ArgumentException( 'charset', $charset, 'Invalid charset!' );
      }

      $this->_attributes[ 'charset' ] = $charset;

      return $this;

   }