gan_formatter.php
function format_html(&$root, $recursive = null) {
		if ($recursive === null) {
			$recursive = true;
			self::minify_html($root);
		} elseif (is_int($recursive)) {
			$recursive = (($recursive > 1) ? $recursive - 1 : false);
		}

		$root_tag = strtolower($root->tag);
		$in_block = isset($this->block_elements[$root_tag]) && $this->block_elements[$root_tag]['as_block'];
		$child_count = count($root->children);

		if (isset($this->options['attributes_case']) && $this->options['attributes_case']) {
			$root->attributes = array_change_key_case($root->attributes, $this->options['attributes_case']);
			$root->attributes_ns = null;
		}

		if (isset($this->options['sort_attributes']) && $this->options['sort_attributes']) {
			if ($this->options['sort_attributes'] === 'reverse') {
				krsort($root->attributes);
			} else {
				ksort($root->attributes);
			}
		}

		if ($root->select(':element', true, false, true)) {
			$root->setTag(strtolower($root->tag), true);
			if (($this->options['img_alt'] !== null) && ($root_tag === 'img') && (!isset($root->alt))) {
                $root->setAttribute('alt', $this->options['img_alt']);
			}
		}
		if ($this->options['self_close_str'] !== null) {
			$root->self_close_str = $this->options['self_close_str'];
		}
		if ($this->options['attribute_shorttag'] !== null) {
			$root->attribute_shorttag = $this->options['attribute_shorttag'];
		}

		$prev = null;
		$n_tag = '';
//		$prev_tag = '';
		$as_block = false;
		$prev_asblock = false;
		for($i = 0; $i < $child_count; $i++) {
			$n =& $root->children[$i];
			$indent = $n->indent();

			if (!$n->isText()) {
				$n_tag = strtolower($n->tag);
				$new_line = isset($this->block_elements[$n_tag]) && $this->block_elements[$n_tag]['new_line'];
				$as_block = isset($this->block_elements[$n_tag]) && $this->block_elements[$n_tag]['as_block'];
				$format_inside = ((!isset($this->block_elements[$n_tag])) || $this->block_elements[$n_tag]['format_inside']);

				if ($prev && ($prev->isText()) && $prev->text && ($char = $prev->text[strlen($prev->text) - 1]) && isset($this->whitespace[$char])) {
					if ($this->whitespace[$char]) {
						$prev->text .= str_repeat($this->indent_string, $indent);
					} else {
						$prev->text = substr_replace($prev->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), -1, 1);
					}
				} elseif (($new_line || $prev_asblock || ($in_block && ($i === 0)))){
					if ($prev && ($prev->isText())) {
						$prev->text .= $this->linebreak_string.str_repeat($this->indent_string, $indent);
					} else {
						$root->addText($this->linebreak_string.str_repeat($this->indent_string, $indent), $i);
						++$child_count;
					}
				}

				if ($format_inside && count($n->children)) {
					//$last = end($n->children);
					$last = $n->children[count($n->children) - 1];
					$last_tag = ($last) ? strtolower($last->tag) : '';
					$last_asblock = ($last_tag && isset($this->block_elements[$last_tag]) && $this->block_elements[$last_tag]['as_block']);

					if (($n->childCount(true) > 0) || (trim($n->getPlainText()))) {
						if ($last && ($last->isText()) && $last->text && ($char = $last->text[strlen($last->text) - 1]) && isset($this->whitespace[$char])) {
							if ($as_block || ($last->index() > 0) || isset($this->whitespace[$last->text[0]])) {
								if ($this->whitespace[$char]) {
									$last->text .= str_repeat($this->indent_string, $indent);
								} else {
									$last->text = substr_replace($last->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), -1, 1);
								}
							}
						} elseif (($as_block || $last_asblock || ($in_block && ($i === 0))) && $last) {
							if ($last && ($last->isText())) {
								$last->text .= $this->linebreak_string.str_repeat($this->indent_string, $indent);
							} else {
								$n->addText($this->linebreak_string.str_repeat($this->indent_string, $indent));
							}
						}
					} elseif (!trim($n->getInnerText())) {
						$n->clear();
					}

					if ($recursive) {
						$this->format_html($n, $recursive);
					}
				}

			} elseif (trim($n->text) && ((($i - 1 < $child_count) && ($char = $n->text[0]) && isset($this->whitespace[$char])) || ($in_block && ($i === 0)))) {
				if (isset($this->whitespace[$char])) {
					if ($this->whitespace[$char]) {
						$n->text = str_repeat($this->indent_string, $indent).$n->text;
					} else {
						$n->text = substr_replace($n->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), 0, 1);
					}
				} else {
					$n->text = $this->linebreak_string.str_repeat($this->indent_string, $indent).$n->text;
				}
			}

			$prev = $n;
//			$prev_tag = $n_tag;
			$prev_asblock = $as_block;
		}

		return true;
	}
function format_html(&$root, $recursive = null) {
		if ($recursive === null) {
			$recursive = true;
			self::minify_html($root);
		} elseif (is_int($recursive)) {
			$recursive = (($recursive > 1) ? $recursive - 1 : false);
		}

		$root_tag = strtolower($root->tag);
		$in_block = isset($this->block_elements[$root_tag]) && $this->block_elements[$root_tag]['as_block'];
		$child_count = count($root->children);

		if (isset($this->options['attributes_case']) && $this->options['attributes_case']) {
			$root->attributes = array_change_key_case($root->attributes, $this->options['attributes_case']);
			$root->attributes_ns = null;
		}

		if (isset($this->options['sort_attributes']) && $this->options['sort_attributes']) {
			if ($this->options['sort_attributes'] === 'reverse') {
				krsort($root->attributes);
			} else {
				ksort($root->attributes);
			}
		}

		if ($root->select(':element', true, false, true)) {
			$root->setTag(strtolower($root->tag), true);
			if (($this->options['img_alt'] !== null) && ($root_tag === 'img') && (!isset($root->alt))) {
                $root->setAttribute('alt', $this->options['img_alt']);
			}
		}
		if ($this->options['self_close_str'] !== null) {
			$root->self_close_str = $this->options['self_close_str'];
		}
		if ($this->options['attribute_shorttag'] !== null) {
			$root->attribute_shorttag = $this->options['attribute_shorttag'];
		}

		$prev = null;
		$n_tag = '';
//		$prev_tag = '';
		$as_block = false;
		$prev_asblock = false;
		for($i = 0; $i < $child_count; $i++) {
			$n =& $root->children[$i];
			$indent = $n->indent();

			if (!$n->isText()) {
				$n_tag = strtolower($n->tag);
				$new_line = isset($this->block_elements[$n_tag]) && $this->block_elements[$n_tag]['new_line'];
				$as_block = isset($this->block_elements[$n_tag]) && $this->block_elements[$n_tag]['as_block'];
				$format_inside = ((!isset($this->block_elements[$n_tag])) || $this->block_elements[$n_tag]['format_inside']);

				if ($prev && ($prev->isText()) && $prev->text && ($char = $prev->text[strlen($prev->text) - 1]) && isset($this->whitespace[$char])) {
					if ($this->whitespace[$char]) {
						$prev->text .= str_repeat($this->indent_string, $indent);
					} else {
						$prev->text = substr_replace($prev->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), -1, 1);
					}
				} elseif (($new_line || $prev_asblock || ($in_block && ($i === 0)))){
					if ($prev && ($prev->isText())) {
						$prev->text .= $this->linebreak_string.str_repeat($this->indent_string, $indent);
					} else {
						$root->addText($this->linebreak_string.str_repeat($this->indent_string, $indent), $i);
						++$child_count;
					}
				}

				if ($format_inside && count($n->children)) {
					//$last = end($n->children);
					$last = $n->children[count($n->children) - 1];
					$last_tag = ($last) ? strtolower($last->tag) : '';
					$last_asblock = ($last_tag && isset($this->block_elements[$last_tag]) && $this->block_elements[$last_tag]['as_block']);

					if (($n->childCount(true) > 0) || (trim($n->getPlainText()))) {
						if ($last && ($last->isText()) && $last->text && ($char = $last->text[strlen($last->text) - 1]) && isset($this->whitespace[$char])) {
							if ($as_block || ($last->index() > 0) || isset($this->whitespace[$last->text[0]])) {
								if ($this->whitespace[$char]) {
									$last->text .= str_repeat($this->indent_string, $indent);
								} else {
									$last->text = substr_replace($last->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), -1, 1);
								}
							}
						} elseif (($as_block || $last_asblock || ($in_block && ($i === 0))) && $last) {
							if ($last && ($last->isText())) {
								$last->text .= $this->linebreak_string.str_repeat($this->indent_string, $indent);
							} else {
								$n->addText($this->linebreak_string.str_repeat($this->indent_string, $indent));
							}
						}
					} elseif (!trim($n->getInnerText())) {
						$n->clear();
					}

					if ($recursive) {
						$this->format_html($n, $recursive);
					}
				}

			} elseif (trim($n->text) && ((($i - 1 < $child_count) && ($char = $n->text[0]) && isset($this->whitespace[$char])) || ($in_block && ($i === 0)))) {
				if (isset($this->whitespace[$char])) {
					if ($this->whitespace[$char]) {
						$n->text = str_repeat($this->indent_string, $indent).$n->text;
					} else {
						$n->text = substr_replace($n->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), 0, 1);
					}
				} else {
					$n->text = $this->linebreak_string.str_repeat($this->indent_string, $indent).$n->text;
				}
			}

			$prev = $n;
//			$prev_tag = $n_tag;
			$prev_asblock = $as_block;
		}

		return true;
	}
Formats HTML
@param DomNode $root
@param bool $recursive
@access private