)/U', $html, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); $dom = self::parseDom($elements); $indent = 0; $output = array(); foreach ($dom as $index => $element) { if ($element['opening']) { $output[] = "\n".str_repeat($indentWith, $indent).trim($element['content']); // make sure that only the elements who have not been blacklisted are being indented if ( ! in_array($element['type'], explode(',', $tagsWithoutIndentation))) { ++$indent; } } else if ($element['standalone']) { $output[] = "\n".str_repeat($indentWith, $indent).trim($element['content']); } else if ($element['closing']) { --$indent; $lf = "\n".str_repeat($indentWith, abs($indent)); if (isset($dom[$index - 1]) && $dom[$index - 1]['opening']) { $lf = ''; } $output[] = $lf.trim($element['content']); } else if ($element['text']) { // $output[] = "\n".str_repeat($indentWith, $indent).trim($element['content']); $output[] = "\n".str_repeat($indentWith, $indent).preg_replace('/ [ \t]*/', ' ', $element['content']); } else if ($element['comment']) { $output[] = "\n".str_repeat($indentWith, $indent).trim($element['content']); } } return trim(implode('', $output)); } /** * Parses an array of HTML tokens and adds basic information about about the type of * tag the token represents. * * @param Array $elements Array of HTML tokens (tags and text tokens). * @return Array HTML elements with extra information. */ public static function parseDom(Array $elements) { $dom = array(); foreach ($elements as $element) { $isText = false; $isComment = false; $isClosing = false; $isOpening = false; $isStandalone = false; $currentElement = trim($element); // comment if (strpos($currentElement, '$/', $currentElement)) { $isStandalone = true; } // normal opening tag else if (strpos($currentElement, '<') === 0) { $isOpening = true; } // text else { $isText = true; } $dom[] = array( 'text' => $isText, 'comment' => $isComment, 'closing' => $isClosing, 'opening' => $isOpening, 'standalone' => $isStandalone, 'content' => $element, 'type' => preg_replace('/^<\/?(\w+)[ >].*$/U', '$1', $element) ); } return $dom; } }