Removes whitespace from a PHP source string while preserving line numbers.

@param  string $source A PHP string
@return string The PHP string with the whitespace removed
344938
private function stripWhitespace($source)
    {
        // Verificar se token_get_all existe
        if (! function_exists('token_get_all')) {
            return $source;
        }

        $output = '';
        foreach (token_get_all($source) as $token) {
            if (is_string($token)) {
                $output .= $token;
            } elseif (in_array($token[0], [T_COMMENT, T_DOC_COMMENT])) {
                $output .= str_repeat("\n", substr_count($token[1], "\n"));
            } elseif (T_WHITESPACE === $token[0]) {
                // reduce wide spaces
                $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
                // normalize newlines to \n
                $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
                // trim leading spaces
                $whitespace = preg_replace('{\n +}', "\n", $whitespace);
                $output .= $whitespace;
            } else {
                $output .= $token[1];
            }
        }

        return $output;
    }
601976
public static function getClassNamespace($source)
    {
        $fullClassName = self::getClassName($source);

        if (null === $fullClassName || '' === $fullClassName) {
            return '';
        }

        $className = self::getClassName($source, true);

        if ($className === $fullClassName) {
            return $className;
        }

        return Miscellaneous::getStringWithoutLastElement($fullClassName, '\\');
    }
741437
public function parse($source)
		{
		// Reset
		$this->source = "";
		$this->tokens = array();
		// Create a global and plugin lookup table for trigger chars; set array of plugins as local variable and create 
		// several helper variables for plugin handling
		$globalTriggerChars		= "";
		$plugins				= $this->plugins;
		$pluginCount			= count($plugins);
		$pluginIndex			= array();
		$pluginTriggerStates	= array();
		$pluginTriggerChars		= array();
		for ($i = 0, $l = count($plugins); $i < $l; $i++)
			{
			$tPluginClassName				= get_class($plugins[$i]);
			$pluginTriggerChars[$i]			= implode("", $plugins[$i]->getTriggerChars());
			$tPluginTriggerStates			= $plugins[$i]->getTriggerStates();
			$pluginTriggerStates[$i]		= $tPluginTriggerStates === false ? false : "|" . implode("|", $tPluginTriggerStates) . "|";
			$pluginIndex[$tPluginClassName]	= $i;
			for ($ii = 0, $ll = strlen($pluginTriggerChars[$i]); $ii < $ll; $ii++)
				{
				$c = substr($pluginTriggerChars[$i], $ii, 1);
				if (strpos($globalTriggerChars, $c) === false)
					{
					$globalTriggerChars .= $c;
					}
				}
			}
		// Normalise line endings
		$source			= str_replace("\r\n", "\n", $source);	// Windows to Unix line endings
		$source			= str_replace("\r", "\n", $source);		// Mac to Unix line endings
		$this->source	= $source;
		// Variables
		$buffer			= &$this->buffer;
		$exclusive		= &$this->stateExclusive;
		$state			= &$this->state;
		$c = $p 		= null;
		// --
		for ($i = 0, $l = strlen($source); $i < $l; $i++)
			{
			// Set the current Char
			$c = $source[$i]; // Is faster than: $c = substr($source, $i, 1);
			// Normalize and filter double whitespace characters
			if ($exclusive === false)
				{
				if ($c === "\n" || $c === "\t")
					{
					$c = " ";
					}
				if ($c === " " && $p === " ")
					{
					continue;
					}
				}
			$buffer .= $c;
			// Extended processing only if the current char is a global trigger char
			if (strpos($globalTriggerChars, $c) !== false)
				{
				// Exclusive state is set; process with the exclusive plugin 
				if ($exclusive)
					{
					$tPluginIndex = $pluginIndex[$exclusive];
					if (strpos($pluginTriggerChars[$tPluginIndex], $c) !== false && ($pluginTriggerStates[$tPluginIndex] === false || strpos($pluginTriggerStates[$tPluginIndex], $state) !== false))
						{
						$r = $plugins[$tPluginIndex]->parse($i, $c, $p, $state);
						// Return value is TRUE => continue with next char
						if ($r === true)
							{
							continue;
							}
						// Return value is numeric => set new index and continue with next char
						elseif ($r !== false && $r != $i)
							{
							$i = $r;
							continue;
							}
						}
					}
				// Else iterate through the plugins
				else
					{
					$triggerState = "|" . $state . "|";
					for ($ii = 0, $ll = $pluginCount; $ii < $ll; $ii++)
						{
						// Only process if the current char is one of the plugin trigger chars
						if (strpos($pluginTriggerChars[$ii], $c) !== false && ($pluginTriggerStates[$ii] === false || strpos($pluginTriggerStates[$ii], $triggerState) !== false))
							{
							// Process with the plugin
							$r = $plugins[$ii]->parse($i, $c, $p, $state);
							// Return value is TRUE => break the plugin loop and and continue with next char
							if ($r === true)
								{
								break;
								}
							// Return value is numeric => set new index, break the plugin loop and and continue with next char
							elseif ($r !== false && $r != $i)
								{
								$i = $r;
								break;
								}
							}
						}
					}
				}
			$p = $c; // Set the parent char
			}
		return $this->tokens;
		}
387641
function appendString($source)
    {
        $this->tokenization = array('');
        for ($i = 0; $i < strlen($source); $i++) {
            if (strlen($this->ansi)) {
                $this->ansi.= $source[$i];
                $chr = ord($source[$i]);
                // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
                // single character CSI's not currently supported
                switch (true) {
                    case $this->ansi == "\x1B=":
                        $this->ansi = '';
                        continue 2;
                    case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
                    case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
                        break;
                    default:
                        continue 2;
                }
                $this->tokenization[] = $this->ansi;
                $this->tokenization[] = '';
                // http://ascii-table.com/ansi-escape-sequences-vt-100.php
                switch ($this->ansi) {
                    case "\x1B[H": // Move cursor to upper left corner
                        $this->old_x = $this->x;
                        $this->old_y = $this->y;
                        $this->x = $this->y = 0;
                        break;
                    case "\x1B[J": // Clear screen from cursor down
                        $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
                        $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));

                        $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
                        $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));

                        if (count($this->history) == $this->max_history) {
                            array_shift($this->history);
                            array_shift($this->history_attrs);
                        }
                    case "\x1B[K": // Clear screen from cursor right
                        $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);

                        array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
                        break;
                    case "\x1B[2K": // Clear entire line
                        $this->screen[$this->y] = str_repeat(' ', $this->x);
                        $this->attrs[$this->y] = $this->attr_row;
                        break;
                    case "\x1B[?1h": // set cursor key to application
                    case "\x1B[?25h": // show the cursor
                    case "\x1B(B": // set united states g0 character set
                        break;
                    case "\x1BE": // Move to next line
                        $this->_newLine();
                        $this->x = 0;
                        break;
                    default:
                        switch (true) {
                            case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
                                $this->old_y = $this->y;
                                $this->y+= $match[1];
                                break;
                            case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
                                $this->old_x = $this->x;
                                $this->old_y = $this->y;
                                $this->x = $match[2] - 1;
                                $this->y = $match[1] - 1;
                                break;
                            case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
                                $this->old_x = $this->x;
                                $this->x+= $match[1];
                                break;
                            case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
                                $this->old_x = $this->x;
                                $this->x-= $match[1];
                                if ($this->x < 0) {
                                    $this->x = 0;
                                }
                                break;
                            case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
                                break;
                            case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
                                $attr_cell = &$this->attr_cell;
                                $mods = explode(';', $match[1]);
                                foreach ($mods as $mod) {
                                    switch ($mod) {
                                        case 0: // Turn off character attributes
                                            $attr_cell = clone $this->base_attr_cell;
                                            break;
                                        case 1: // Turn bold mode on
                                            $attr_cell->bold = true;
                                            break;
                                        case 4: // Turn underline mode on
                                            $attr_cell->underline = true;
                                            break;
                                        case 5: // Turn blinking mode on
                                            $attr_cell->blink = true;
                                            break;
                                        case 7: // Turn reverse video on
                                            $attr_cell->reverse = !$attr_cell->reverse;
                                            $temp = $attr_cell->background;
                                            $attr_cell->background = $attr_cell->foreground;
                                            $attr_cell->foreground = $temp;
                                            break;
                                        default: // set colors
                                            //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
                                            $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
                                            //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
                                            $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
                                            switch ($mod) {
                                                // @codingStandardsIgnoreStart
                                                case 30: $front = 'black'; break;
                                                case 31: $front = 'red'; break;
                                                case 32: $front = 'green'; break;
                                                case 33: $front = 'yellow'; break;
                                                case 34: $front = 'blue'; break;
                                                case 35: $front = 'magenta'; break;
                                                case 36: $front = 'cyan'; break;
                                                case 37: $front = 'white'; break;

                                                case 40: $back = 'black'; break;
                                                case 41: $back = 'red'; break;
                                                case 42: $back = 'green'; break;
                                                case 43: $back = 'yellow'; break;
                                                case 44: $back = 'blue'; break;
                                                case 45: $back = 'magenta'; break;
                                                case 46: $back = 'cyan'; break;
                                                case 47: $back = 'white'; break;
                                                // @codingStandardsIgnoreEnd

                                                default:
                                                    //user_error('Unsupported attribute: ' . $mod);
                                                    $this->ansi = '';
                                                    break 2;
                                            }
                                    }
                                }
                                break;
                            default:
                                //user_error("{$this->ansi} is unsupported\r\n");
                        }
                }
                $this->ansi = '';
                continue;
            }

            $this->tokenization[count($this->tokenization) - 1].= $source[$i];
            switch ($source[$i]) {
                case "\r":
                    $this->x = 0;
                    break;
                case "\n":
                    $this->_newLine();
                    break;
                case "\x08": // backspace
                    if ($this->x) {
                        $this->x--;
                        $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell;
                        $this->screen[$this->y] = substr_replace(
                            $this->screen[$this->y],
                            $source[$i],
                            $this->x,
                            1
                        );
                    }
                    break;
                case "\x0F": // shift
                    break;
                case "\x1B": // start ANSI escape code
                    $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
                    //if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
                    //    array_pop($this->tokenization);
                    //}
                    $this->ansi.= "\x1B";
                    break;
                default:
                    $this->attrs[$this->y][$this->x] = clone $this->attr_cell;
                    if ($this->x > strlen($this->screen[$this->y])) {
                        $this->screen[$this->y] = str_repeat(' ', $this->x);
                    }
                    $this->screen[$this->y] = substr_replace(
                        $this->screen[$this->y],
                        $source[$i],
                        $this->x,
                        1
                    );

                    if ($this->x > $this->max_x) {
                        $this->x = 0;
                        $this->_newLine();
                    } else {
                        $this->x++;
                    }
            }
        }
    }
941482
private function adaptString($source)
    {
        foreach ($this->pattern_adapters as $pattern => $adapter) {
            $pattern = '/'.str_replace('/', '\\/', $pattern).'/i';
            if (preg_match($pattern, $source)) {
                return $adapter;
            }
        }
    }
680454
public function rel($source)
    {
        $fullpath = (string)$this->get($source);
        return FS::getRelative($fullpath, $this->root, '/');
    }
263673
public function parsePoSource(string $source): void
    {
        /**
         * This is an incredibly ugly regex pattern that breaks a line of a po file into
         * pieces that can be analyzed and acted upon.
         *
         * The matches array in preg_match will break out like this:
         *  [0] full string
         *  [1] mostly useless broad match of initial token, including trailing space
         *  [2] bare token, or full msgstr[n] clause
         *  [3] 'n' of a msgstr[n] line
         *  [4] '"' if a data line
         *  [5] remaining line
         *  [6] a bare or malformed comment
         */
        $pattern = '/(^(#|#.|#;|#,|#\||msgid|msgid_plural|msgctxt|msgstr|msgstr\[([0-9]+)\])\s|(^"))(.+)|(^#.*)/';

        $source_lines = explode("\n", $source);

        $wsBreak = false;
        $inHeader = true;
        $headerEntry = new PoHeader;
        $entry = $headerEntry;
        $unrecognized = array();
        $lastKey = '';
        $currentPlural = 0;
        foreach ($source_lines as $line => $s) {
            $result = preg_match($pattern, $s, $matches);
            if (!$result) {
                $lastKey = '';
                if ($s=='' || ctype_space($s)) {
                    if ($inHeader) {
                        $this->setHeaderEntry($headerEntry);
                        $entry = null;
                        $inHeader = false;
                    }
                    if (!$wsBreak) {
                        if (!($entry === null)) {
                            $this->addEntry($entry);
                        }
                        $entry = null;
                        $wsBreak=true;
                    }
                } else {
                    $wsBreak=false;
                    $unrecognized[$line+1] = $s;
                }
            } else {
                if ($entry === null) {
                    $entry = new PoEntry;
                }
                $wsBreak=false;
                $currentKey = $matches[2];  // will be used to set last key
                switch ($matches[2]) {
                    case PoTokens::TRANSLATOR_COMMENTS:
                    case PoTokens::EXTRACTED_COMMENTS:
                    case PoTokens::REFERENCE:
                    case PoTokens::FLAG:
                    case PoTokens::OBSOLETE:
                    case PoTokens::PREVIOUS:
                        $entry->add($matches[2], $matches[5]);
                        break;
                    case PoTokens::CONTEXT:
                    case PoTokens::MESSAGE:
                    case PoTokens::PLURAL:
                    case PoTokens::TRANSLATED:
                        $entry->addQuoted($matches[2], $matches[5]);
                        break;
                    default:
                        if ($matches[4]==PoTokens::CONTINUED_DATA) {
                            $currentKey = $lastKey; // keep the previous key
                            if ($currentKey==PoTokens::TRANSLATED_PLURAL) {
                                $entry->addQuotedAtPosition(
                                    PoTokens::TRANSLATED,
                                    $currentPlural,
                                    '"' . $matches[5]
                                );
                            } else {
                                $entry->addQuoted($currentKey, '"' . $matches[5]);
                            }
                        } elseif (substr($matches[2], 0, 7)==PoTokens::TRANSLATED_PLURAL) {
                            $currentKey = PoTokens::TRANSLATED_PLURAL;
                            $currentPlural = $matches[3];
                            $entry->addQuotedAtPosition(
                                PoTokens::TRANSLATED,
                                $currentPlural,
                                $matches[5]
                            );
                        } elseif (isset($matches[6][0])
                            && $matches[6][0]==PoTokens::TRANSLATOR_COMMENTS) {
                            $value = substr($matches[6], 1);
                            $value = empty($value) ? '' : $value;
                            $entry->add(PoTokens::TRANSLATOR_COMMENTS, $value);
                        } else {
                            $unrecognized[$line+1] = $s;
                        }
                        break;
                }
                $lastKey = $currentKey;
            }
        }
        if (!($entry === null)) {
            $this->addEntry($entry);
        }

        // throw at the very end, anything recognized has been processed
        $this->unrecognizedInput = $unrecognized;
        if (count($unrecognized)) {
            throw new UnrecognizedInputException();
        }
    }
789970
protected function _cleanTags($source)
    {
        $preTag         = null;
        $postTag        = $source;

        // Is there a tag? If so it will certainly start with a '<'
        $tagOpen_start  = strpos($source, '<');

        while ($tagOpen_start !== false)
        {
            // Get some information about the tag we are processing
            $preTag         .= substr($postTag, 0, $tagOpen_start);
            $postTag        = substr($postTag, $tagOpen_start);
            $fromTagOpen    = substr($postTag, 1);
            $tagOpen_end    = strpos($fromTagOpen, '>');

            // Let's catch any non-terminated tags and skip over them
            if ($tagOpen_end === false) {
                $postTag        = substr($postTag, $tagOpen_start +1);
                $tagOpen_start  = strpos($postTag, '<');
                continue;
            }

            // Do we have a nested tag?
            $tagOpen_nested = strpos($fromTagOpen, '<');
            if (($tagOpen_nested !== false) && ($tagOpen_nested < $tagOpen_end)) {
                $preTag         .= substr($postTag, 0, ($tagOpen_nested +1));
                $postTag        = substr($postTag, ($tagOpen_nested +1));
                $tagOpen_start  = strpos($postTag, '<');
                continue;
            }

            // Lets get some information about our tag and setup attribute pairs
            $currentTag     = substr($fromTagOpen, 0, $tagOpen_end);
            $tagLength      = strlen($currentTag);
            $tagLeft        = $currentTag;
            $attrSet        = array ();
            $currentSpace   = strpos($tagLeft, ' ');

            // Are we an open tag or a close tag?
            if (substr($currentTag, 0, 1) == '/') {
                // Close Tag
                $isCloseTag     = true;
                list ($tagName) = explode(' ', $currentTag);
                $tagName        = substr($tagName, 1);
            } else {
                // Open Tag
                $isCloseTag     = false;
                list ($tagName) = explode(' ', $currentTag);
            }

            /*
             * Exclude all "non-regular" tagnames
             * OR no tagname
             * OR remove if xssauto is on and tag is blacklisted
             */
            if ((!preg_match("/^[a-z][a-z0-9]*$/i", $tagName)) || (!$tagName) || ((in_array(strtolower($tagName), $this->_tagBlacklist)) && ($this->_xssAuto))) {
                $postTag        = substr($postTag, ($tagLength +2));
                $tagOpen_start  = strpos($postTag, '<');
                // Strip tag
                continue;
            }

            /*
             * Time to grab any attributes from the tag... need this section in
             * case attributes have spaces in the values.
             */
            while ($currentSpace !== false)
            {
                $attr           = '';
                $fromSpace      = substr($tagLeft, ($currentSpace +1));
                $nextSpace      = strpos($fromSpace, ' ');
                $openQuotes     = strpos($fromSpace, '"');
                $closeQuotes    = strpos(substr($fromSpace, ($openQuotes +1)), '"') + $openQuotes +1;

                // Do we have an attribute to process? [check for equal sign]
                if (strpos($fromSpace, '=') !== false) {
                    /*
                     * If the attribute value is wrapped in quotes we need to
                     * grab the substring from the closing quote, otherwise grab
                     * till the next space
                     */
                    if (($openQuotes !== false) && (strpos(substr($fromSpace, ($openQuotes +1)), '"') !== false)) {
                        $attr = substr($fromSpace, 0, ($closeQuotes +1));
                    } else {
                        $attr = substr($fromSpace, 0, $nextSpace);
                    }
                } else {
                    /*
                     * No more equal signs so add any extra text in the tag into
                     * the attribute array [eg. checked]
                     */
                    if ($fromSpace != '/') {
                        $attr = substr($fromSpace, 0, $nextSpace);
                    }
                }

                // Last Attribute Pair
                if (!$attr && $fromSpace != '/') {
                    $attr = $fromSpace;
                }

                // Add attribute pair to the attribute array
                $attrSet[] = $attr;

                // Move search point and continue iteration
                $tagLeft        = substr($fromSpace, strlen($attr));
                $currentSpace   = strpos($tagLeft, ' ');
            }

            // Is our tag in the user input array?
            $tagFound = in_array(strtolower($tagName), $this->_tagsArray);

            // If the tag is allowed lets append it to the output string
            if ((!$tagFound && $this->_tagsMethod) || ($tagFound && !$this->_tagsMethod)) {

                // Reconstruct tag with allowed attributes
                if (!$isCloseTag) {
                    // Open or Single tag
                    $attrSet = $this->_cleanAttributes($attrSet);
                    $preTag .= '<'.$tagName;
                    for ($i = 0; $i < count($attrSet); $i ++)
                    {
                        $preTag .= ' '.$attrSet[$i];
                    }

                    // Reformat single tags to XHTML
                    if (strpos($fromTagOpen, '</'.$tagName)) {
                        $preTag .= '>';
                    } else {
                        $preTag .= ' />';
                    }
                } else {
                    // Closing Tag
                    $preTag .= '</'.$tagName.'>';
                }
            }

            // Find next tag's start and continue iteration
            $postTag        = substr($postTag, ($tagLength +2));
            $tagOpen_start  = strpos($postTag, '<');
        }

        // Append any code after the end of tags and return
        if ($postTag != '<') {
            $preTag .= $postTag;
        }
        return $preTag;
    }
529502
public static function whitespace($str='', int $newlines=0) {
		ref\sanitize::whitespace($str, $newlines);
		return $str;
	}
143285
public function provide(string $source): string
    {
        if (!$this->filesystem->fileExists($source)) {
            throw WsdlException::notFound($source);
        }

        return $source;
    }
1267838
protected function encodeArrayName(array $source): string
    {
        $source = $this->encodeArray($source);
        $count = count($source);
        if ($count === 2 || $count === 3) {
            $name = array_pop($source);
            $method = implode('::', $source);
            return sprintf('%s() $%s parameter', $method, $name);
        } else {
            return implode('::', $source);
        }
    }
89493
protected function lowercase( array $source )
    {
    	$result = array();

    	foreach ($source as $key => $value )
    		$result[strtolower($key)] = $value;

    	return $result;
    }
746406
public static function translateFile($source)
    {
        if ($source == null) {
            return "";
        }

        $result = $source;
        for ($i = 0, $_i = strlen($source); $i < $_i; $i++) {
            self::translateFileSep($result, $i);
        }

        return $result;
    }
63906
public function truncate($source)
    {
        if ($pos = strpos($source, '.')) {
            $db = substr($source, 0, $pos);
            $collection = substr($source, $pos + 1);
        } else {
            $db = $this->_default_db;
            $collection = $source;
        }

        try {
            $this->command(['drop' => $collection], $db);
            return true;
        } catch (RuntimeException $e) {
            /**
             * https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err
             * error_code("NamespaceNotFound", 26)
             */
            if ($e->getCode() === 26) {
                return true;
            } else {
                throw $e;
            }
        }
    }
1263768
public final static function encode(array $source): string {
		if (($source = json_encode($source)) == false && json_last_error() !== JSON_ERROR_NONE){
			throw new \Exception('Invalid raw data!');
		}

		return $source;
	}
287872
public static function spaceless(string $string): string
	{
		$string = self::trim($string);
		$string = self::replace($string, '#\s{2,}#', ' ');
		return $string;
	}
177032
private function removeWhitespace(): void
    {
        $string = preg_replace('/ {2,}/', Tokens::SPACE, $this->normalisedString);
        $lines = [];

        foreach (explode(Tokens::LINE_FEED, $string) as $line) {
            if ('' !== $line = trim($line)) {
                $lines[] = $line;
            }
        }
        $this->normalisedString = implode(Tokens::LINE_FEED, $lines);
    }