Repair HTML. If Tidy not exists, use repair function.

@param   string  $html     The HTML string to repair.
@param   boolean $use_tidy Force tidy or not.

@return  string  Repaired HTML.
497543
public static function repair($html, $use_tidy = true)
    {
        if (function_exists('tidy_repair_string') && $use_tidy) {
            $TidyConfig = [
                'indent' => true,
                'output-xhtml' => true,
                'show-body-only' => true,
                'wrap' => false,
            ];

            return tidy_repair_string($html, $TidyConfig, 'utf8');
        } else {
            $arr_single_tags = ['meta', 'img', 'br', 'link', 'area'];

            // Put all opened tags into an array
            preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU", $html, $result);
            $openedtags = $result[1];

            // Put all closed tags into an array
            preg_match_all("#</([a-z]+)>#iU", $html, $result);

            $closedtags = $result[1];
            $len_opened = count($openedtags);

            // All tags are closed
            if (count($closedtags) == $len_opened) {
                return $html;
            }

            $openedtags = array_reverse($openedtags);

            // Close tags
            for ($i = 0; $i < $len_opened; $i++) {
                if (!in_array($openedtags[$i], $closedtags)) {
                    if (!in_array($openedtags[$i], $arr_single_tags)) {
                        $html .= "</" . $openedtags[$i] . ">";
                    }
                } else {
                    unset($closedtags[array_search($openedtags[$i], $closedtags)]);
                }
            }

            return $html;
        }
    }
1332153
public function last($html, $html2 = '')
    {
        # Only show if you are not on the last page
        $r = ($this->get < $this->pages()) ? str_replace('{nr}', $this->pages(), $html) : str_replace('{nr}', $this->pages(), $html2);

        return $r;
    }
538135
public function convert($html)
    {
        $html = parent::convert((string) $html);

        $html = $this->encode('--', '-', $html, false);
        $html = $this->encode('\#', '#', $html);
        $html = $this->encode('\*', '*', $html);
        $html = $this->encode('\_', '_', $html);
        $html = $this->encode('•', '*', $html);
        $html = $this->encode('…', '...', $html);

        $html = $this->encode('\[', '[', (string) $html);
        $html = $this->encode('\]', ']', (string) $html);
        $html = str_replace(array('—', '–', '\-'), '-', $html);
        $html = str_replace(array('“', '”'), '"', $html);
        $html = str_replace(array('’', '‘'), "'", $html);
        $html = str_replace("\n\n\n", "\n\n", $html);
        $html = str_replace("\n ", "\n", (string) $html);

        return str_replace('\.', '.', (string) $html);
    }
1188414
public function convertToString($html)
    {
        $externalJavaScript = $this->extractExternalJavaScript($html);

        return $this->replaceJavaScriptTags($html, $externalJavaScript);
    }
1083850
protected function cleaningHtml($html)
    {
        $xml = false;
        $childrens = null;

        try {
            $xml = @simplexml_load_string($html);
        } catch (\Exception $e) {
            // ignore
        }

        if ($xml !== false) {
            if (!$this->hasHead && $xml->getName() === 'head') {
                $childrens = $xml->xpath('//head/child::*');
            }
            if (!$this->hasBody && $xml->getName() === 'body') {
                $childrens = $xml->xpath('//body/child::*');
            }

            if ($childrens !== null) {
                $temp = '';
                foreach ($childrens as $children) {
                    $temp .= $children->saveXML();
                }
                $html = html_entity_decode($temp);
            }
        }

        if ($this->hasHtml) {
            $html = $this->htmlMatches['before'].$html.$this->htmlMatches['after'];
        }
        if ($this->hasDoctype) {
            $html = $this->doctypeMatches['content'].$html;
        }

        return $html;
    }
1318471
private static function convertHtmlToDom($html)
    {
        $dom = new DOMDocument;

        \libxml_use_internal_errors(true);
        $dom->loadHTML($html);

        \libxml_clear_errors();

        return $dom;
    }
1238789
protected function decodeHtml($html): string
    {
        $text = html_entity_decode($html);
        $text = preg_replace('#<br\s*/?>#', LF, $text);

        return $text;
    }
319269
public function fixNonvoidTags($html) {
        return preg_replace_callback('~(<([\w]+)[^>]*?)(\s*/>)~u', function ($matches) {
            // something went wrong
            if(empty($matches[2])) {
                // do nothing
                return $matches[0];
            }
            // regular void elements
            if(in_array($matches[2], array('area','base','br','col','embed','hr','img','input','keygen','link','meta','param','source','track','wbr'))) {
                // do nothing
                return $matches[0];
            }
            // correctly closed element
            return trim(mb_substr($matches[0], 0, -2), 'UTF-8') . '></' . $matches[2] . '>';
        }, $html);
    }
1119535
def tidyHTML(dirtyHTML):
    
    try:
        from tidylib import tidy_document
    except ImportError as e:
        raise ImportError(("%s\nYou need to install pytidylib.\n" +
             "e.g. sudo pip install pytidylib") % e)
    options = {
        'output-xhtml':1,
        #add_xml_decl=1,#option in tidy but not pytidylib
        'indent':1,
        'tidy-mark':1,
        #'char-encoding':'utf8',
        'char-encoding':'raw',
    }
    html, errors = tidy_document(dirtyHTML, options=options)
    return html
312047
private function createDOMDocumentFromHTML($html = null) {

        if ($html != null) {
            libxml_use_internal_errors(true);
            $dom = new DOMDocument;
            $dom->loadHTML($html);
            libxml_clear_errors();
            libxml_use_internal_errors(false);
            return $dom;
        }
    }
201682
public function readability_html( $html )
	{
		$data = $this->post_call('/readability', ['html' => $html ] );

		return ( !empty($data['readability']) ) ? $data['readability'] : null;
	}
353967
public function setHtml(string $html=null, bool $append=true) :self {
		// append by default or replace html
		$this->content = $append ? $this->content . $html : $html;
		// return self
		return($this);
	}
643854
public function first($html, $html2 = '')
    {
        # Only show if you are not on page 1, otherwise show HTML2
        $r = ($this->get != 1) ? str_replace('{nr}', 1, $html) : str_replace('{nr}', 1, $html2);

        return $r;
    }
1014740
static function pre(string $html=null):self{
    return self::create(__FUNCTION__,self::NOSELF|self::RAW)($html);//FIXME pre和code，谁包裹谁？？？
  }
266813
public function replace($html)
    {
        $this->setOption(self::OPTION_VALUE, $html);
        $this->setOption(self::OPTION_METHOD, 'replace');

        return $this;
    }
1226169
public function tidy($use_default = true)
    {
        if ($use_default) {
            return isset($this->tidy) ? $this->tidy : $this->default_tidy;
        }

        return $this->tidy;
    }
859517
def _post_tidy(html):
    
    tree = etree.fromstring(html)
    ems = tree.xpath(
        "//xh:em[@class='underline']|//xh:em[contains(@class, ' underline ')]",
        namespaces={'xh': 'http://www.w3.org/1999/xhtml'})
    for el in ems:
        c = el.attrib.get('class', '').split()
        c.remove('underline')
        el.tag = '{http://www.w3.org/1999/xhtml}u'
        if c:
            el.attrib['class'] = ' '.join(c)
        elif 'class' in el.attrib:
            del(el.attrib['class'])

    return tree