Apply ansi formatting to output according to tags

@param string $output
@return string
332676
protected function formatOutput($output)
    {
        $tagFormats = $this->tagFormats;
        $disableAnsi = $this->disableAnsi;
        do {
            $lastOutput = $output;
            $output = preg_replace_callback('|(<([^>]+?)>(.*?)</\2>)|s', function ($matches) use ($tagFormats, $disableAnsi) {
                $format = isset($tagFormats[$matches[2]]) ? $tagFormats[$matches[2]] : '|';
                if ($disableAnsi) {
                    return $matches[3];
                } else {
                    return str_replace('|', $matches[3], $format);
                }
            }, $output);
        } while ($lastOutput !== $output);
        return $output;
    }
60787
private function cleanExtraPlaceholders($output)
    {
        if (false !== strpos($output, '%')) {
            $output = preg_replace('/%(?:extra|context)\..+?%/', '', $output);
            $output = preg_replace('/ %type%\n/', "\n", $output);
            $output = preg_replace('/on line %line%/', '', $output);
            $output = preg_replace('/ in %file% /', '', $output);
        }

        return $output;
    }
819994
public function parseDiffOutput($output, array $arguments = array())
    {
        if (!isset($arguments['--name-status']) || false === $arguments['--name-status']) {
            // non name-status results are not supported
            return $output;
        }

        $lines = explode("\n", rtrim($output));

        $retval = array();
        foreach ($lines as $line) {
            if (preg_match('/([ACDMRTUXB])(\d*)\s+(.*)?/', $line, $matches)) {
                list($fullmatch, $status, $number, $filename) = $matches;

                if ($number && preg_match('/(.*\s)+(.*)/', $filename, $filenameMatches)) {
                    list($fullmatch, $originalName, $filename) = $filenameMatches;
                }

                $file = new VcsFileInfo($filename, $this->getClient()->getHead());
                $file->setStatus($status);

                $retval[] = $file;
            } else {
                throw new \Exception('Unable to parse line "'. $line . '"');
            }
        }

        return $retval;
    }
1209331
protected function cleanOutput($output)
    {
        $output = str_replace($this->extraOutput, null, $output);

        return strtr($output, [
            'stdin: is not a tty' => null,
        ]);
    }
530868
public static function outputStyles($output = '')
    {
        self::lookIfProcessFiles('style', 'header');

        $template = self::$templates['style'];
        $styles = self::$data['style']['header'];

        foreach ($styles as $value) {
            $output .= sprintf(
                $template,
                $value['url']
            );
        }

        self::$data['style']['header'] = [];

        return ! empty($output) ? $output : false;
    }
301965
private function formatBlock($output, $background, $foreground, $large = false)
    {
        /** @var FormatterHelper $formatter */
        $formatter = $this->getApplication()->getHelperSet()->get('formatter');

        return $formatter->formatBlock($output, "bg={$background};fg={$foreground}", $large);
    }
163909
public function compile($output)
    {
        file_exists($output) || mkdir($output);

        $this->clear((string) $output);

        $this->output = (string) $output;

        foreach ((array) $this->pages as $page) {
            $folder = $this->folder($output, $page->uris());

            $html = (string) $this->html($page);

            $path = $this->realpath($output . '/' . $folder);

            file_put_contents($path . 'index.html', $html);
        }

        return $this;
    }
150291
protected function getWebPath($output)
    {
        $path = trim(dirname($output), '/');
        $count = count(explode('/', $path));

        $path = '';

        for ($i = 0; $i < $count-1; $i++) {
            $path.= '/..';
        }

        return $path;
    }
890273
protected function parseLogOutput($output, array $arguments = array())
    {
        if (!isset($arguments['--xml']) || false === $arguments['--xml']) {
            // non xml results are not supported
            return $output;
        }

        $sxml = simplexml_load_string($output);

        $retval = array();
        foreach ($sxml->logentry as $entry) {
            $revision = (string) $entry->attributes()->revision;
            $date     = (string) $entry->date;
            $author   = (string) $entry->author;
            $message  = (string) $entry->msg;

            $retval[] = new Commit($revision, new \DateTime($date), $author, trim($message));
        }

        return $retval;
    }
1032456
private static function cleanHTML($output)
    {
        $output = preg_replace('/<title>.*<\/title>/smi', '', $output);
        $output = preg_replace('/<style>.*<\/style>/smi', '', $output);
        $output = strip_tags($output);
        $output = preg_replace('/(\n+)(\s+)/smi', "\n", $output);
        $output = preg_replace('/&nbsp;/smi', ' ', $output);

        return $output;
    }
894440
public function format($string, $format = null) {
        if ($format === null) {
            $format = $this->getOutputFormat();
        }

        // print output with ansi support
        if (($format & OutputFormat::NORMAL) === OutputFormat::NORMAL) {
            return $this->formatter->formatAnsi($string);
        }
        // print output without ansi support
        else if (($format & OutputFormat::PLAIN) === OutputFormat::PLAIN) {
            return $this->formatter->formatPlain($string);
        }

        // return raw output
        return $string;
    }
60242
public function output($output) {
		return fwrite($this->output, Text::insert($output, $this->styles()));
	}
28053
public static function format($output)
	{
		$output->addString('The profile log has the following format (');
		$output->addString('* indicates visible field', array('color'=>'blue'));
		$output->addLine('):');

		$i = 0;
		foreach (static::$fields as $field => $status)
		{
			if ($i != 0)
			{
				$output->addString(' ');
			}

			$output->addString('<');

			if ($i < 10)
			{
				$output->addString($i . ':');
			}

			if ($status)
			{
				$output->addString('*' . $field, array('color'=>'blue'));
			}
			else
			{
				$output->addString($field);
			}

			$output->addString('>');
			$i++;
		}

		$output->addSpacer()->addSpacer();
	}
1174894
protected function escapeColumns(array $output)
    {
        return array_map(function ($row) {
            if ($this->escapeColumns == '*') {
                $row = $this->escapeRow($row);
            } elseif (is_array($this->escapeColumns)) {
                $columns = array_diff($this->escapeColumns, $this->rawColumns);
                foreach ($columns as $key) {
                    array_set($row, $key, e(array_get($row, $key)));
                }
            }

            return $row;
        }, $output);
    }
968458
protected function indent(&$result) {
        /// Replace tabs with the correct number of spaces
        if (false !== strpos($result, "\t")) {
            $lines = explode("\n", $result);
            $result = null;//Save memory while we process the lines individually
            $tab_width = $this->get_real_tab_width();
            $tab_string = '&nbsp;' . str_repeat(' ', $tab_width);

            for ($key = 0, $n = count($lines); $key < $n; $key++) {
                $line = $lines[$key];
                if (false === strpos($line, "\t")) {
                    continue;
                }

                $pos = 0;
                $length = strlen($line);
                $lines[$key] = ''; // reduce memory

                $IN_TAG = false;
                for ($i = 0; $i < $length; ++$i) {
                    $char = $line[$i];
                    // Simple engine to work out whether we're in a tag.
                    // If we are we modify $pos. This is so we ignore HTML
                    // in the line and only workout the tab replacement
                    // via the actual content of the string
                    // This test could be improved to include strings in the
                    // html so that < or > would be allowed in user's styles
                    // (e.g. quotes: '<' '>'; or similar)
                    if ($IN_TAG) {
                        if ('>' == $char) {
                            $IN_TAG = false;
                        }
                        $lines[$key] .= $char;
                    } elseif ('<' == $char) {
                        $IN_TAG = true;
                        $lines[$key] .= '<';
                    } elseif ('&' == $char) {
                        $substr = substr($line, $i + 3, 5);
                        $posi = strpos($substr, ';');
                        if (false === $posi) {
                            ++$pos;
                        } else {
                            $pos -= $posi+2;
                        }
                        $lines[$key] .= $char;
                    } elseif ("\t" == $char) {
                        $str = '';
                        // OPTIMISE - move $strs out. Make an array:
                        // $tabs = array(
                        //  1 => '&nbsp;',
                        //  2 => '&nbsp; ',
                        //  3 => '&nbsp; &nbsp;' etc etc
                        // to use instead of building a string every time
                        $tab_end_width = $tab_width - ($pos % $tab_width); //Moved out of the look as it doesn't change within the loop
                        if (($pos & 1) || 1 == $tab_end_width) {
                            $str .= substr($tab_string, 6, $tab_end_width);
                        } else {
                            $str .= substr($tab_string, 0, $tab_end_width+5);
                        }
                        $lines[$key] .= $str;
                        $pos += $tab_end_width;

                        if (false === strpos($line, "\t", $i + 1)) {
                            $lines[$key] .= substr($line, $i + 1);
                            break;
                        }
                    } elseif (0 == $pos && ' ' == $char) {
                        $lines[$key] .= '&nbsp;';
                        ++$pos;
                    } else {
                        $lines[$key] .= $char;
                        ++$pos;
                    }
                }
            }
            $result = implode("\n", $lines);
            unset($lines);//We don't need the lines separated beyond this --- free them!
        }
        // Other whitespace
        // BenBE: Fix to reduce the number of replacements to be done
        $result = preg_replace('/^ /m', '&nbsp;', $result);
        $result = str_replace('  ', ' &nbsp;', $result);

        if ($this->line_numbers == GESHI_NO_LINE_NUMBERS && $this->header_type != GESHI_HEADER_PRE_TABLE) {
            if ($this->line_ending === null) {
                $result = nl2br($result);
            } else {
                $result = str_replace("\n", $this->line_ending, $result);
            }
        }
    }
668493
protected function generateAndAttachLinkHeaders ($output)
    {
        $settings = Http2ServerPush::$plugin->getSettings();

        $headers = $this->fetchLinkableNodes($output, $settings->includeImages)
                        ->flatten(1)
                        ->map(function ($url) {
                            return $this->buildLinkHeaderString($url);
                        })
                        ->filter()
                        ->take($settings->limit)
                        ->implode(',');

        if ( !empty(trim($headers)) ) {
            $this->addLinkHeader($headers);
        }

        return $output;
    }
1076834
protected function getVendorPath($output)
    {
        $path = trim(dirname($output), '/');
        $count = count(explode('/', $path));

        $path = '';

        for ($i = 0; $i < $count; $i++) {
            $path.= '/..';
        }

        return $path . '/vendor/';
    }