Compile the proper template inheritance for the lines.

@param  array  $lines
@return array
966585
protected function compileLayoutExtends($lines)
	{
		$pattern = $this->createMatcher('extends');

		$lines[] = preg_replace($pattern, '$1@include$2', $lines[0]);

		return $lines;
	}
159659
protected static function fixLastLine(array $lines, array $all): array
    {
        $last = end($all);
        $lastLine = end($lines);
        if ($lastLine !== false && $last !== $lastLine && rtrim($lastLine) === $last) {
            $lines[key($lines)] = $last;
        }
        return $lines;
    }
1022953
public function _processClassDocLine($line)
    {
        $result = null;
        if (preg_match(self::PATTERN_METHOD, $line, $matches)) {
            /* parse and transform template's data */
            $isRequired = true;
            $returnType = $matches[1];
            /* replace '|null' in the end of the return type and mark as not required */
            $key = '|null';
            $length = strlen($key);
            if (substr($returnType, -$length, $length) == $key) {
                $returnType = str_replace($key, '', $returnType);
                $isRequired = false;
            }
            $methodName = lcfirst($matches[2]);
            $paramsCount = $this->_getRequiredParamsCount($matches[3]);
            $desc = $matches[4]??'';
            $desc = trim($desc);
            /* compose result  */
            $result = new \Praxigento\Core\App\Reflection\Data\Method();
            $result->setName($methodName);
            $result->setIsRequired($isRequired);
            $result->setType($returnType);
            $result->setDescription($desc);
            $result->setParameterCount($paramsCount);
        }
        return $result;
    }
140890
protected function formatExtraLines($lines)
    {
        foreach ($lines as $pos => $line) {
            $lines[$pos] = '      * '.$line;
        }
        return $lines;
    }
975908
public function parseLines(array $lines)
    {
        $config = new SiteConfig();

        foreach ($lines as $line) {
            $line = trim($line);

            // skip comments, empty lines
            if ('' === $line || '#' === $line[0]) {
                continue;
            }

            // get command
            $command = explode(':', $line, 2);
            // if there's no colon ':', skip this line
            if (2 !== \count($command)) {
                continue;
            }

            $val = trim($command[1]);
            $command = trim($command[0]);
            if ('' === $command || '' === $val) {
                continue;
            }

            // check for commands where we accept multiple statements
            if (\in_array($command, ['title', 'body', 'strip', 'strip_id_or_class', 'strip_image_src', 'single_page_link', 'next_page_link', 'test_url', 'find_string', 'replace_string', 'login_extra_fields', 'native_ad_clue', 'date', 'author', 'strip_attr'], true)) {
                array_push($config->$command, $val);
            // check for single statement commands that evaluate to true or false
            } elseif (\in_array($command, ['tidy', 'prune', 'autodetect_on_failure', 'requires_login', 'skip_json_ld'], true)) {
                $config->$command = ('yes' === $val || 'true' === $val);
            // check for single statement commands stored as strings
            } elseif (\in_array($command, ['parser', 'login_username_field', 'login_password_field', 'not_logged_in_xpath', 'login_uri', 'src_lazy_load_attr'], true)) {
                $config->$command = $val;
            // check for replace_string(find): replace
            } elseif ((')' === substr($command, -1)) && preg_match('!^([a-z0-9_]+)\((.*?)\)$!i', $command, $match) && 'replace_string' === $match[1]) {
                array_push($config->find_string, $match[2]);
                array_push($config->replace_string, $val);
            } elseif ((')' === substr($command, -1)) && preg_match('!^([a-z0-9_]+)\(([a-z0-9_-]+)\)$!i', $command, $match) && 'http_header' === $match[1] && \in_array(strtolower($match[2]), ['user-agent', 'referer', 'cookie', 'accept'], true)) {
                $config->http_header[strtolower(trim($match[2]))] = $val;
            // special treatment for if_page_contains
            } elseif (\in_array($command, ['if_page_contains'], true)) {
                $this->handleIfPageContainsCondition($config, $val);
            }
        }

        return $config;
    }
334575
public static function indentLines($lines, $indent = '  ')
    {
        $lineSeparator = "\n";
        $buffer        = '';
        $line          = strtok($lines, $lineSeparator);
        while ($line) {
            $buffer .= $indent . $line . $lineSeparator;
            $line = strtok($lineSeparator);
        }
        strtok(null, null);

        return $buffer;
    }
454256
public function parseRemoteBranches(array $lines)
    {
        $branches = [];
        $delimiter = ' ';
        foreach ($lines as $line) {
            $line = trim($line);
            $line = preg_replace('/\s+/', ' ', $line);
            $parts = explode($delimiter, $line);
            if (count($parts) > 1) {
                $branches[$parts[0]] = ['local_relationship' => $parts[1]];
            }
        }

        return $branches;
    }
788466
private function appendLines(array $lines, bool $trim): void
  {
    foreach ($lines as $line)
    {
      $this->appendLine($line, $trim);
    }
  }
159926
public static function prependLines( $lines, $prepend, $prependFirstLine = false )
	{
		$new = [];
		$lines = str_contains( $lines, '\r\n' ) ? explode( "\r\n", $lines ) : explode( "\n", $lines );

		if ( !$prependFirstLine )
			$new[] = $lines[0];

		for ( $i = $prependFirstLine ? 0 : 1; $i < count( $lines ); $i++ )
			$new[] = $prepend . $lines[$i];

		return implode( "\n", $new );
	}
379520
protected function mergeDuplicates(array $line)
    {
        $values = [];

        $i = 0;
        foreach ($this->columnHeaders as $count) {
            if (1 === $count) {
                $values[] = $line[$i];
            } else {
                $values[] = array_slice($line, $i, $count);
            }

            $i += $count;
        }

        return $values;
    }
1235708
public function parseLocalPushRefs($lines)
    {
        $branches = [];
        $delimiter = ' pushes to ';
        foreach ($lines as $line) {
            $line = trim($line);
            $line = preg_replace('/\s+/', ' ', $line);
            $parts = explode($delimiter, $line);
            if (count($parts) > 1) {
                $value = explode(' ', $parts[1], 2);
                $branches[$parts[0]] = ['pushes_to' => $value[0], 'local_state' => $value[1]];
            }
        }

        return $branches;
    }
91735
public function setLines($lines)
    {
        if (!is_array($lines)) {
            $this->lines = array(
                $lines
            );
        } else {
            $this->lines = $lines;
        }

        return $this;
    }
549934
private function parseLine($line)
    {
        if (!$line) {
            return array();
        }

        $line = trim($line);

        if (!$line) {
            return array();
        }

        $array = array();
        $group = $this->nodeContainsGroup($line);

        if ($group) {
            $this->addGroup($line, $group);
            $line = $this->stripGroup ($line, $group);
        }
        if ($this->startsMappedSequence($line)) {
            return $this->returnMappedSequence($line);
        }
        if ($this->startsMappedValue($line)) {
            return $this->returnMappedValue($line);
        }
        if ($this->isArrayElement($line)) {
            return $this->returnArrayElement($line);
        }
        if ($this->isPlainArray($line)) {
            return $this->returnPlainArray($line);
        }

        return $this->returnKeyValuePair($line);
    }
84526
private function getIndent(array $lines)
    {
        $detector = new IndentationDetector(
            LineCollection::createFromArray($lines)
        );

        return str_repeat(' ', $detector->getFirstLineIndentation());
    }
1150857
private function parseOutputLines(array $lines)
    {
        foreach ($lines as $line) {
            preg_match('/([MADRCU\? ])?([MADRCU\? ])?\ "?(\S+)"? ?( -> )?(\S+)?/', $line, $matches);
            $x = isset($matches[1]) ? $matches[1] : null;
            $y = isset($matches[2]) ? $matches[2] : null;
            $file = isset($matches[3]) ? $matches[3] : null;
            $renamedFile = isset($matches[4]) ? $matches[4] : null;
            $this->files[] = StatusFile::create($x, $y, $file, $renamedFile);
        }
    }
947386
protected function parseAirlines(array $airlines)
    {
        $parsed = [];

        foreach ($airlines as $airline) {
            $parsed[$airline['fs']] = $airline;
        }

        return $parsed;
    }
482692
private function parseDocBlock( $lines )
	{
#		remark( "Parsing DocBlock" );
		$data		= array();
		$descLines	= array();
		foreach( $lines as $line )
		{
			if( preg_match( $this->regexDocParam, $line, $matches ) )
			{
				$param	= array(
					'type'			=> $matches[2],
					'name'			=> $matches[4],
					'description'	=> isset( $matches[5] ) ? $matches[5] : NULL,
				);
				if( !isset( $data['param'] ) )
					$data['param']	= array();
				$data['param'][$matches[4]]	= $param;
			}
			else if( preg_match( "@\*\s+\@return\s+(\w+)\s*(.+)?$@i", $line, $matches ) )
			{
				$data['return']	= array(
					'type'			=> trim( $matches[1] ),
					'description'	=> isset( $matches[2] ) ? trim( $matches[2] ) : "",
				);
			}
			else if( preg_match( "@\*\s+\@author\s+(.+)\s*(<(.+)>)?$@iU", $line, $matches ) )
			{
				$data['author'][]	= array(
					'name'	=> trim( $matches[1] ),
					'mail'	=> isset( $matches[3] ) ? trim( $matches[3] ) : "",
				);
			}
			else if( preg_match( "@\*\s+\@license\s+(\S+)( .+)?$@i", $line, $matches ) )
			{
				if( isset( $matches[2] ) )
				{
					$url	= trim( $matches[1] );
					$name	= trim( $matches[2] );
					if( preg_match( "@^http://@", $matches[2] ) )
					{
						$url	= trim( $matches[2] );
						$name	= trim( $matches[1] );
					}
				}
				else
				{
					$url	= "";
					$name	= trim( $matches[1] );
					if( preg_match( "@^http://@", $matches[1] ) )
						$url	= trim( $matches[1] );
				}
			
				$data['license'][]	= array(
					'url'	=> $url,
					'name'	=> $name,
				);
			}
			else if( preg_match( "/^\*\s+@(\w+)\s+(.+)$/", $line, $matches ) )
			{
				switch( $matches[1] )
				{
					case 'implements':
					case 'deprecated':
					case 'todo':
					case 'see':
					case 'link':
					case 'copyright':
					case 'license':
					case 'author':
					case 'see':
					case 'uses':
					case 'throws':
					case 'link':
						$data[$matches[1]][]	= $matches[2];			
						break;
					default:
						$data[$matches[1]]	= $matches[2];			
						break;
				}
			}
			else if( !$data && preg_match( "/^\*\s*([^@].+)?$/", $line, $matches ) )
				$descLines[]	= isset( $matches[1] ) ? trim( $matches[1] ) : "";
		}
		$data['description']	= trim( implode( "\n", $descLines ) );
		if( !isset( $data['throws'] ) )
			$data['throws']	= array();
		foreach( $data['throws'] as $throws )
		{
			$list	= array();
			$parts	= explode( ",", $throws );
			foreach( $parts as $part )
				$list[]	= trim( $part );
			$data['throws']	= $list;
		}
		return $data;
	}