/*!
\static
Returns an HTML highlighted and displayable formatted HTML from the
input text. < and > are converted to &lt; and &gt;
503275
function highlightHTML( $input )
    {
        $input = str_replace( "<", "&lt;", $input );
        $input = str_replace( ">", "&gt;", $input );

        $input = preg_replace( "#&lt;(.*?)&gt;#m", "<font color='red'>&lt;$1&gt;</font>", $input );

        return $input;
    }
269379
public static function to_html( $v ) {
		if ( self::is_embedded_html( $v ) ) {
			return $v['html']; } elseif ( self::is_microformat( $v ) ) {
			return htmlspecialchars( $v['value'] ); }
			return htmlspecialchars( $v );
	}
1126745
public function asPlainText(): string
    {
        return $this->text ?? $this->text = (new Html2Text($this->html))->getText();
    }
856092
public function html()
    {
        if (!$this->hasContent() && !$this->isEditable()) {
            return '';
        }

        $content = $this->hasContent() ? $this->show() : $this->showDefault();

        // If the return data is a View then assign any parameters to it.
        if ($content instanceof View && !empty($this->viewParams)) {
            $content->with($this->viewParams);
        }

        return (string) $content;
    }
1324817
public function Plain()
    {
        // Preserve line breaks
        $text = preg_replace('/\<br(\s*)?\/?\>/i', "\n", $this->RAW());

        // Convert paragraph breaks to multi-lines
        $text = preg_replace('/\<\/p\>/i', "\n\n", $text);

        // Strip out HTML tags
        $text = strip_tags($text);

        // Implode >3 consecutive linebreaks into 2
        $text = preg_replace('~(\R){2,}~', "\n\n", $text);

        // Decode HTML entities back to plain text
        return trim(Convert::xml2raw($text));
    }
1107532
public function toHtml() {

        // Add the class at the last minute.
        if ($this->get_force_ltr()) {
            if (!isset($this->_attributes['class'])) {
                $this->_attributes['class'] = 'text-ltr';
            } else {
                $this->_attributes['class'] .= ' text-ltr';
            }
        }

        $this->_generateId();
        if ($this->_flagFrozen) {
            return $this->getFrozenHtml();
        }
        $html = $this->_getTabs() . '<input' . $this->_getAttrString($this->_attributes) . ' />';

        if ($this->_hiddenLabel){
            return '<label class="accesshide" for="'.$this->getAttribute('id').'" >'.
                        $this->getLabel() . '</label>' . $html;
        } else {
             return $html;
        }
    }
124097
static function __static()
	{
		XmlTypeCode::$typeToCodeMap = array(
			'xs:anyType'				=> XmlTypeCode::AnyType,
			'xs:anySimpleType'			=> XmlTypeCode::AnyAtomicType,
			'xs:untypedAtomic'			=> XmlTypeCode::UntypedAtomic,
			'xs:string'					=> XmlTypeCode::String,
			'xs:boolean'				=> XmlTypeCode::Boolean,
			'xs:decimal'				=> XmlTypeCode::Decimal,
			'xs:double'					=> XmlTypeCode::Double,
			'xs:float'					=> XmlTypeCode::Float,
			'xs:duration'				=> XmlTypeCode::Duration,
			'xs:dateTime'				=> XmlTypeCode::DateTime,
			'xs:time'					=> XmlTypeCode::Time,
			'xs:date'					=> XmlTypeCode::Date,
			'xs:gYearMonth'				=> XmlTypeCode::GYearMonth,
			'xs:gYear'					=> XmlTypeCode::GYear,
			'xs:gMonthDay'				=> XmlTypeCode::GMonthDay,
			'xs:gDay'					=> XmlTypeCode::GDay,
			'xs:gMonth'					=> XmlTypeCode::GMonth,
			'xs:hexBinary'				=> XmlTypeCode::HexBinary,
			'xs:base64Binary'			=> XmlTypeCode::Base64Binary,
			'xs:anyURI'					=> XmlTypeCode::AnyUri,
			'xs:QName'					=> XmlTypeCode::QName,
			'xs:NOTATION'				=> XmlTypeCode::Notation,
			'xs:normalizedString'		=> XmlTypeCode::NormalizedString,
			'xs:token'					=> XmlTypeCode::Token,
			'xs:language'				=> XmlTypeCode::Language,
			'xs:Name'					=> XmlTypeCode::Name,
			'xs:NCName'					=> XmlTypeCode::NCName,
			'xs:NMTOKEN'				=> XmlTypeCode::NmToken,
			'xs:ID'						=> XmlTypeCode::Id,
			'xs:IDREF'					=> XmlTypeCode::Idref,
			'xs:ENTITY'					=> XmlTypeCode::Entity,
			'xs:integer'				=> XmlTypeCode::Integer,
			'xs:nonPositiveInteger'		=> XmlTypeCode::NonPositiveInteger,
			'xs:long'					=> XmlTypeCode::Long,
			'xs:nonNegativeInteger'		=> XmlTypeCode::NonNegativeInteger,
			'xs:negativeInteger' 		=> XmlTypeCode::NegativeInteger,
			'xs:int'					=> XmlTypeCode::Int,
			'xs:short'					=> XmlTypeCode::Short,
			'xs:byte'					=> XmlTypeCode::Byte,
			'xs:positiveInteger' 		=> XmlTypeCode::PositiveInteger,
			'xs:unsignedLong' 			=> XmlTypeCode::UnsignedLong,
			'xs:unsignedInt' 			=> XmlTypeCode::UnsignedInt,
			'xs:unsignedShort'			=> XmlTypeCode::UnsignedShort,
			'xs:unsignedByte'			=> XmlTypeCode::UnsignedByte,
			'xs:IDREFS'					=> XmlTypeCode::IDREFS,
			'xs:ENTITIES'				=> XmlTypeCode::ENTITIES,
			'xs:NMTOKENS'				=> XmlTypeCode::NMTOKENS,
			'xs:yearMonthDuration'		=> XmlTypeCode::YearMonthDuration,
			'xs:dayTimeDuration'		=> XmlTypeCode::DayTimeDuration,
			'xs:UNION'					=> XmlTypeCode::UNION,
		);

		XmlTypeCode::$codeToTypeMap = array_flip( XmlTypeCode::$typeToCodeMap );
	}
747153
public function highlight($htmlString)
    {
        $tags = implode('|', $this->validContainers);
        $pattern = '#(<(' . $tags . ')[^>]'.$this->langAttribute . '=["\']+([^\'".]*)["\']+>)(.*?)(</\2\s*>|$)#s';
        /*
         matches[0] = whole string
         matches[1] = open tag including lang attribute
         matches[2] = tag name
         matches[3] = value of lang attribute
         matches[4] = text to be highlighted
         matches[5] = end tag
        */
        return preg_replace_callback($pattern, array($this, '_processCodeBlock'), $htmlString);
    }
501822
public function getHtml(): string
  {
    $html = $this->prefix;
    $html .= Html::generateTag('span', $this->attributes);

    if (is_array($this->options))
    {
      // Normalize current value as a string.
      $valueAsString = Cast::toManString($this->value, '');

      foreach ($this->options as $option)
      {
        $inputAttributes = $this->inputAttributes($option);
        $labelAttributes = $this->labelAttributes($option);

        $labelAttributes['for'] = $inputAttributes['id'];

        $key         = $option[$this->keyKey];
        $keyAsString = Cast::toManString($key, '');
        $value       = ($this->optionsObfuscator) ? $this->optionsObfuscator->encode(Cast::toOptInt($key)) : $key;

        $inputAttributes['value']   = $value;
        $inputAttributes['checked'] = ($valueAsString===$keyAsString);

        $html .= Html::generateVoidElement('input', $inputAttributes);

        $html .= $this->labelPrefix;
        $html .= Html::generateElement('label',
                                       $labelAttributes,
                                       Cast::toOptString($option[$this->labelKey]),
                                       $this->labelIsHtml);
        $html .= $this->labelPostfix;
      }
    }

    $html .= '</span>';
    $html .= $this->postfix;

    return $html;
  }
729877
function text()
	{
		if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER];
		switch ($this->nodetype)
		{
			case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
			case HDOM_TYPE_COMMENT: return '';
			case HDOM_TYPE_UNKNOWN: return '';
		}
		if (strcasecmp($this->tag, 'script')===0) return '';
		if (strcasecmp($this->tag, 'style')===0) return '';

		$ret = '';
		// In rare cases, (always node type 1 or HDOM_TYPE_ELEMENT - observed for some span tags, and some p tags) $this->nodes is set to NULL.
		// NOTE: This indicates that there is a problem where it's set to NULL without a clear happening.
		// WHY is this happening?
		if (!is_null($this->nodes))
		{
			foreach ($this->nodes as $n)
			{
				$ret .= $this->convert_text($n->text());
			}

			// If this node is a span... add a space at the end of it so multiple spans don't run into each other.  This is plaintext after all.
			if ($this->tag == "span")
			{
				$ret .= $this->dom->default_span_text;
			}


		}
		return $ret;
	}
99068
public function html($with_js = 1)
	{
    $html = '';
		if ( $this->tag ){
			$this->update();
      // TAG
			$html .= '<'.$this->tag;

      foreach ( $this->attr as $key => $val ){
        if ( \is_string($key) ){
          $html .= ' '.htmlspecialchars($key).'="';
          if ( is_numeric($val) ){
            $html .= $val;
          }
          else if (\is_string($val) ){
            $html .= htmlspecialchars($val);
          }
          $html .= '"';
        }
      }
			
      if ( \count($this->css) > 0 ){
				$html .= self::css_to_string($this->css);
			}
      if ( $this->xhtml ){
        $html .= ' /';
      }
      $html .= '>';

			
			if ( !\in_array($this->tag, self::$self_closing_tags) ){

        if ( isset($this->text) ){
          $html .= $this->text;
        }
        
        if ( isset($this->content) ){
          // @todo: Add the ability to imbricate elements
          if ( \is_string($this->content) ){
            $html .= $this->content;
          }
          else if ( \is_array($this->content) ){
            foreach ( $this->content as $c ){
              if ( \is_array($c) ){
                $c = new bbn\html\element($c);
              }
              $html .= $c->html($with_js);
            }
          }
        }
				$html .= '</'.$this->tag.'>';
			}
			
			if ( isset($this->placeholder) && strpos($this->placeholder,'%s') !== false ){
				$html = sprintf($this->placeholder, $html);
			}
      
		}
		return $html;
	}
1357190
public function prepareHtml($html)
    {
        // if it is a real html page, we have to convert it
        if (preg_match('/<body/isU', $html)) {
            $html = $this->getHtmlFromRealPage($html);
        }

        // replace some constants
        $html = str_replace('[[date_y]]', date('Y'), $html);
        $html = str_replace('[[date_m]]', date('m'), $html);
        $html = str_replace('[[date_d]]', date('d'), $html);

        $html = str_replace('[[date_h]]', date('H'), $html);
        $html = str_replace('[[date_i]]', date('i'), $html);
        $html = str_replace('[[date_s]]', date('s'), $html);

        return $html;
    }
430880
public String prettyHtml() {
        StringBuilder html = new StringBuilder();
        for (Change aDiff : getChangeList()) {
            String text = aDiff.text.replace("&", "&amp;")
                                    .replace("<", "&lt;")
                                    .replace(">", "&gt;")
                                    .replace("\n", "&para;<br>");
            switch (aDiff.operation) {
                case INSERT:
                    html.append("<ins style=\"background:#e6ffe6;\">").append(text)
                        .append("</ins>");
                    break;
                case DELETE:
                    html.append("<del style=\"background:#ffe6e6;\">").append(text)
                        .append("</del>");
                    break;
                case EQUAL:
                    html.append("<span>").append(text).append("</span>");
                    break;
            }
        }
        return html.toString();
    }
131469
public function toHtml()
	{
		$html = '';
		
		// if this group isn't a destination
		if ( ! $this->isDestination()) {
			// set the first element's "old" style to the group's style
			$oldStyle = $this->style;
			
			// define a flag indicating whether or not this group is the root group
			//
			// setting this flag here feel a little hackish!
			// however, the first element in the first group is different than the first
			//     element in any other group
			//
			$isFirstGroup = empty($this->parent);
			
			// a flag indicating whether or not the element is the first "textual" element
			//     in the group (i.e., control word with a special symbol, an actual text
			//     element, etc)
			//
			$isFirstTextualElement = true;
			
			// loop through the group's children
			foreach ($this->children as $child) {
				// if the child is a textual element
				$string = $child->format('html');
				if ( ! empty($string)) {
					// get the child's style
					$newStyle = $child->getStyle();
					// if the child is the first textual element in the first (aka, "root") group
					if ($isFirstGroup && $isFirstTextualElement) {
						// open the document's first section, paragraph, and character tags
						$html .= '<section style="'.$newStyle->getSection()->format('css').'">'
							 . '<p style="'.$newStyle->getParagraph()->format('css').'">'
							 . '<span style="'.$newStyle->getCharacter()->format('css').'">';
						// set the flag to false
						$isFirstTextualElement = false;
					} else {
						// otherwise, the child is not the first textual element in the root group 
						//    and we only close and open the section, paragraph, and character tags
						//    if the style has changed between elements
						//
						// keep in mind, a section takes precedence over a paragraph and a character;
						//     a paragraph takes precedence over a character; so on and so forth
						//
						if ($oldStyle->getSection() != $newStyle->getSection()) {
							$html .= '</span></p></section>'
								. '<section style="'.$newStyle->getSection()->format('css').'">'
								. '<p style="'.$newStyle->getParagraph()->format('css').'">'
								. '<span style="'.$newStyle->getCharacter()->format('css').'">';
						} elseif ($oldStyle->getParagraph() != $newStyle->getParagraph()) {
							$html .= '</span></p>'
								. '<p style="'.$newStyle->getParagraph()->format('css').'">'
								. '<span style="'.$newStyle->getCharacter()->format('css').'">';
						} elseif ($oldStyle->getCharacter() != $newStyle->getCharacter()) {
							$html .= '</span>'
								. '<span style="'.$newStyle->getCharacter()->format('css').'">';
						}
					}
					
					// append the html string
					$html .= $string;
					
					// set the "old" style to the current element's style for the next iteration
					$oldStyle = $newStyle;
				}
			}
		}
		
		return $html;
	}
924228
function Html()
    {
        $text = $this->html;
        
        $pos = strpos($text, self::$placeholder);
        $phLength = strlen(self::$placeholder);
        while ($pos !== false && $this->currentChild)
        {
            $replacement = $this->RenderCurrentChild();
            $text = substr($text, 0, $pos) . $replacement . substr($text, $pos + $phLength);
            
            $this->currentChild = $this->tree->NextOf($this->currentChild);
            $pos = strpos($text, self::$placeholder, $pos  + strlen($replacement));
        }
        return $text;
    }
343017
public function getContentHtmlAttribute()
    {
        if ($this->is_html) {
            return $this->content;
        }
        return static::$formatter->render($this->attributes['content'], $this);
    }
674544
protected function getInput()
	{
		$html = array();
		$attr = '';

		// Initialize some field attributes.
		$attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
		$attr .= ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : '';
		$attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
		$attr .= $this->multiple ? ' multiple="multiple"' : '';

		// Initialize JavaScript field attributes.
		$attr .= $this->element['onchange'] ? ' onchange="' . (string) $this->element['onchange'] . '"' : '';

		// Get the field groups.
		$groups = (array) $this->getGroups();

		// Create a read-only list (no name) with a hidden input to store the value.
		if ((string) $this->element['readonly'] == 'true')
		{
			$html[] = HtmlSelect::groupedlist(
				$groups,
				null,
				array(
					'list.attr' => $attr, 'id' => $this->id, 'list.select' => $this->value, 'group.items' => null, 'option.key.toHtml' => false,
					'option.text.toHtml' => false
				)
			);
			$html[] = '<input type="hidden" name="' . $this->name . '" value="' . $this->value . '"/>';
		}
		else
		// Create a regular list.
		{
			$html[] = HtmlSelect::groupedlist(
				$groups,
				$this->name,
				array(
					'list.attr' => $attr, 'id' => $this->id, 'list.select' => $this->value, 'group.items' => null, 'option.key.toHtml' => false,
					'option.text.toHtml' => false
				)
			);
		}

		return implode($html);
	}