parsedown\Parsedown::findBlocks PHP 메소드

findBlocks() 개인적인 메소드

# Private
private findBlocks ( array $lines, $blockContext = null )
$lines array
    private function findBlocks(array $lines, $blockContext = null)
    {
        $block = null;
        $context = null;
        $contextData = null;
        foreach ($lines as $line) {
            $indentedLine = $line;
            $indentation = 0;
            while (isset($line[$indentation]) and $line[$indentation] === ' ') {
                $indentation++;
            }
            if ($indentation > 0) {
                $line = ltrim($line);
            }
            # ~
            switch ($context) {
                case null:
                    $contextData = null;
                    if ($line === '') {
                        continue 2;
                    }
                    break;
                    # ~~~ javascript
                    # var message = 'Hello!';
                # ~~~ javascript
                # var message = 'Hello!';
                case 'fenced code':
                    if ($line === '') {
                        $block['content'][0]['content'] .= "\n";
                        continue 2;
                    }
                    if (preg_match('/^[ ]*' . $contextData['marker'] . '{3,}[ ]*$/', $line)) {
                        $context = null;
                    } else {
                        if ($block['content'][0]['content']) {
                            $block['content'][0]['content'] .= "\n";
                        }
                        $string = htmlspecialchars($indentedLine, ENT_NOQUOTES, 'UTF-8');
                        $block['content'][0]['content'] .= $string;
                    }
                    continue 2;
                case 'markup':
                    if (stripos($line, $contextData['start']) !== false) {
                        $contextData['depth']++;
                    }
                    if (stripos($line, $contextData['end']) !== false) {
                        if ($contextData['depth'] > 0) {
                            $contextData['depth']--;
                        } else {
                            $context = null;
                        }
                    }
                    $block['content'] .= "\n" . $indentedLine;
                    continue 2;
                case 'li':
                    if ($line === '') {
                        $contextData['interrupted'] = true;
                        continue 2;
                    }
                    if ($contextData['indentation'] === $indentation and preg_match('/^' . $contextData['marker'] . '[ ]+(.*)/', $line, $matches)) {
                        if (isset($contextData['interrupted'])) {
                            $nestedBlock['content'][] = '';
                            unset($contextData['interrupted']);
                        }
                        unset($nestedBlock);
                        $nestedBlock = array('name' => 'li', 'content type' => 'lines', 'content' => array($matches[1]));
                        $block['content'][] =& $nestedBlock;
                        continue 2;
                    }
                    if (empty($contextData['interrupted'])) {
                        $value = $line;
                        if ($indentation > $contextData['baseline']) {
                            $value = str_repeat(' ', $indentation - $contextData['baseline']) . $value;
                        }
                        $nestedBlock['content'][] = $value;
                        continue 2;
                    }
                    if ($indentation > 0) {
                        $nestedBlock['content'][] = '';
                        $value = $line;
                        if ($indentation > $contextData['baseline']) {
                            $value = str_repeat(' ', $indentation - $contextData['baseline']) . $value;
                        }
                        $nestedBlock['content'][] = $value;
                        unset($contextData['interrupted']);
                        continue 2;
                    }
                    $context = null;
                    break;
                case 'quote':
                    if ($line === '') {
                        $contextData['interrupted'] = true;
                        continue 2;
                    }
                    if (preg_match('/^>[ ]?(.*)/', $line, $matches)) {
                        $block['content'][] = $matches[1];
                        continue 2;
                    }
                    if (empty($contextData['interrupted'])) {
                        $block['content'][] = $line;
                        continue 2;
                    }
                    $context = null;
                    break;
                case 'code':
                    if ($line === '') {
                        $contextData['interrupted'] = true;
                        continue 2;
                    }
                    if ($indentation >= 4) {
                        if (isset($contextData['interrupted'])) {
                            $block['content'][0]['content'] .= "\n";
                            unset($contextData['interrupted']);
                        }
                        $block['content'][0]['content'] .= "\n";
                        $string = htmlspecialchars($line, ENT_NOQUOTES, 'UTF-8');
                        $string = str_repeat(' ', $indentation - 4) . $string;
                        $block['content'][0]['content'] .= $string;
                        continue 2;
                    }
                    $context = null;
                    break;
                case 'table':
                    if ($line === '') {
                        $context = null;
                        continue 2;
                    }
                    if (strpos($line, '|') !== false) {
                        $nestedBlocks = array();
                        $substring = preg_replace('/^[|][ ]*/', '', $line);
                        $substring = preg_replace('/[|]?[ ]*$/', '', $substring);
                        $parts = explode('|', $substring);
                        foreach ($parts as $index => $part) {
                            $substring = trim($part);
                            $nestedBlock = array('name' => 'td', 'content type' => 'line', 'content' => $substring);
                            if (isset($contextData['alignments'][$index])) {
                                $nestedBlock['attributes'] = array('align' => $contextData['alignments'][$index]);
                            }
                            $nestedBlocks[] = $nestedBlock;
                        }
                        $nestedBlock = array('name' => 'tr', 'content type' => 'blocks', 'content' => $nestedBlocks);
                        $block['content'][1]['content'][] = $nestedBlock;
                        continue 2;
                    }
                    $context = null;
                    break;
                case 'paragraph':
                    if ($line === '') {
                        $block['name'] = 'p';
                        # dense li
                        $context = null;
                        continue 2;
                    }
                    if ($line[0] === '=' and chop($line, '=') === '') {
                        $block['name'] = 'h1';
                        $context = null;
                        continue 2;
                    }
                    if ($line[0] === '-' and chop($line, '-') === '') {
                        $block['name'] = 'h2';
                        $context = null;
                        continue 2;
                    }
                    if (strpos($line, '|') !== false and strpos($block['content'], '|') !== false and chop($line, ' -:|') === '') {
                        $values = array();
                        $substring = trim($line, ' |');
                        $parts = explode('|', $substring);
                        foreach ($parts as $part) {
                            $substring = trim($part);
                            $value = null;
                            if ($substring[0] === ':') {
                                $value = 'left';
                            }
                            if (substr($substring, -1) === ':') {
                                $value = $value === 'left' ? 'center' : 'right';
                            }
                            $values[] = $value;
                        }
                        # ~
                        $nestedBlocks = array();
                        $substring = preg_replace('/^[|][ ]*/', '', $block['content']);
                        $substring = preg_replace('/[|]?[ ]*$/', '', $substring);
                        $parts = explode('|', $substring);
                        foreach ($parts as $index => $part) {
                            $substring = trim($part);
                            $nestedBlock = array('name' => 'th', 'content type' => 'line', 'content' => $substring);
                            if (isset($values[$index])) {
                                $value = $values[$index];
                                $nestedBlock['attributes'] = array('align' => $value);
                            }
                            $nestedBlocks[] = $nestedBlock;
                        }
                        # ~
                        $block = array('name' => 'table', 'content type' => 'blocks', 'content' => array());
                        $block['content'][] = array('name' => 'thead', 'content type' => 'blocks', 'content' => array());
                        $block['content'][] = array('name' => 'tbody', 'content type' => 'blocks', 'content' => array());
                        $block['content'][0]['content'][] = array('name' => 'tr', 'content type' => 'blocks', 'content' => array());
                        $block['content'][0]['content'][0]['content'] = $nestedBlocks;
                        # ~
                        $context = 'table';
                        $contextData = array('alignments' => $values);
                        # ~
                        continue 2;
                    }
                    break;
                default:
                    throw new Exception('Unrecognized context - ' . $context);
            }
            if ($indentation >= 4) {
                $blocks[] = $block;
                $string = htmlspecialchars($line, ENT_NOQUOTES, 'UTF-8');
                $string = str_repeat(' ', $indentation - 4) . $string;
                $block = array('name' => 'pre', 'content type' => 'blocks', 'content' => array(array('name' => 'code', 'content type' => null, 'content' => $string)));
                $context = 'code';
                continue;
            }
            switch ($line[0]) {
                case '#':
                    if (isset($line[1])) {
                        $blocks[] = $block;
                        $level = 1;
                        while (isset($line[$level]) and $line[$level] === '#') {
                            $level++;
                        }
                        $string = trim($line, '# ');
                        $string = $this->parseLine($string);
                        $block = array('name' => 'h' . $level, 'content type' => 'line', 'content' => $string);
                        $context = null;
                        continue 2;
                    }
                    break;
                case '<':
                    $position = strpos($line, '>');
                    if ($position > 1) {
                        $substring = substr($line, 1, $position - 1);
                        $substring = chop($substring);
                        if (substr($substring, -1) === '/') {
                            $isClosing = true;
                            $substring = substr($substring, 0, -1);
                        }
                        $position = strpos($substring, ' ');
                        if ($position) {
                            $name = substr($substring, 0, $position);
                        } else {
                            $name = $substring;
                        }
                        $name = strtolower($name);
                        if ($name[0] == 'h' and strpos('r123456', $name[1]) !== false) {
                            if ($name == 'hr') {
                                $isClosing = true;
                            }
                        } elseif (!ctype_alpha($name)) {
                            break;
                        }
                        if (in_array($name, self::$textLevelElements)) {
                            break;
                        }
                        $blocks[] = $block;
                        $block = array('name' => null, 'content type' => null, 'content' => $indentedLine);
                        if (isset($isClosing)) {
                            unset($isClosing);
                            continue 2;
                        }
                        $context = 'markup';
                        $contextData = array('start' => '<' . $name . '>', 'end' => '</' . $name . '>', 'depth' => 0);
                        if (stripos($line, $contextData['end']) !== false) {
                            $context = null;
                        }
                        continue 2;
                    }
                    break;
                case '>':
                    if (preg_match('/^>[ ]?(.*)/', $line, $matches)) {
                        $blocks[] = $block;
                        $block = array('name' => 'blockquote', 'content type' => 'lines', 'content' => array($matches[1]));
                        $context = 'quote';
                        $contextData = array();
                        continue 2;
                    }
                    break;
                case '[':
                    $position = strpos($line, ']:');
                    if ($position) {
                        $reference = array();
                        $label = substr($line, 1, $position - 1);
                        $label = strtolower($label);
                        $substring = substr($line, $position + 2);
                        $substring = trim($substring);
                        if ($substring === '') {
                            break;
                        }
                        if ($substring[0] === '<') {
                            $position = strpos($substring, '>');
                            if ($position === false) {
                                break;
                            }
                            $reference['link'] = substr($substring, 1, $position - 1);
                            $substring = substr($substring, $position + 1);
                        } else {
                            $position = strpos($substring, ' ');
                            if ($position === false) {
                                $reference['link'] = $substring;
                                $substring = false;
                            } else {
                                $reference['link'] = substr($substring, 0, $position);
                                $substring = substr($substring, $position + 1);
                            }
                        }
                        if ($substring !== false) {
                            if ($substring[0] !== '"' and $substring[0] !== "'" and $substring[0] !== '(') {
                                break;
                            }
                            $lastChar = substr($substring, -1);
                            if ($lastChar !== '"' and $lastChar !== "'" and $lastChar !== ')') {
                                break;
                            }
                            $reference['title'] = substr($substring, 1, -1);
                        }
                        $this->referenceMap[$label] = $reference;
                        continue 2;
                    }
                    break;
                case '`':
                case '~':
                    if (preg_match('/^([`]{3,}|[~]{3,})[ ]*(\\w+)?[ ]*$/', $line, $matches)) {
                        $blocks[] = $block;
                        $block = array('name' => 'pre', 'content type' => 'blocks', 'content' => array(array('name' => 'code', 'content type' => null, 'content' => '')));
                        if (isset($matches[2])) {
                            $block['content'][0]['attributes'] = array('class' => 'language-' . $matches[2]);
                        }
                        $context = 'fenced code';
                        $contextData = array('marker' => $matches[1][0]);
                        continue 2;
                    }
                    break;
                case '-':
                case '*':
                case '_':
                    if (preg_match('/^([-*_])([ ]{0,2}\\1){2,}[ ]*$/', $line)) {
                        $blocks[] = $block;
                        $block = array('name' => 'hr', 'content' => null);
                        continue 2;
                    }
            }
            switch (true) {
                case $line[0] <= '-' and preg_match('/^([*+-][ ]+)(.*)/', $line, $matches):
                case $line[0] <= '9' and preg_match('/^([0-9]+[.][ ]+)(.*)/', $line, $matches):
                    $blocks[] = $block;
                    $name = $line[0] >= '0' ? 'ol' : 'ul';
                    $block = array('name' => $name, 'content type' => 'blocks', 'content' => array());
                    unset($nestedBlock);
                    $nestedBlock = array('name' => 'li', 'content type' => 'lines', 'content' => array($matches[2]));
                    $block['content'][] =& $nestedBlock;
                    $baseline = $indentation + strlen($matches[1]);
                    $marker = $line[0] >= '0' ? '[0-9]+[.]' : '[*+-]';
                    $context = 'li';
                    $contextData = array('indentation' => $indentation, 'baseline' => $baseline, 'marker' => $marker, 'lines' => array($matches[2]));
                    continue 2;
            }
            if ($context === 'paragraph') {
                $block['content'] .= "\n" . $line;
                continue;
            } else {
                $blocks[] = $block;
                $block = array('name' => 'p', 'content type' => 'line', 'content' => $line);
                if ($blockContext === 'li' and empty($blocks[1])) {
                    $block['name'] = null;
                }
                $context = 'paragraph';
            }
        }
        if ($blockContext === 'li' and $block['name'] === null) {
            return $block['content'];
        }
        $blocks[] = $block;
        unset($blocks[0]);
        return $blocks;
    }