parsedown\Parsedown::parseLine PHP Method

parseLine() private method

private parseLine ( $text, $markers = [" ", '![', '&', '*', '<', '[', '\', '_', '`', 'http', '~~'] )
    private function parseLine($text, $markers = array("  \n", '![', '&', '*', '<', '[', '\\', '_', '`', 'http', '~~'))
    {
        if (isset($text[1]) === false or $markers === array()) {
            return $text;
        }
        # ~
        $markup = '';
        while ($markers) {
            $closestMarker = null;
            $closestMarkerIndex = 0;
            $closestMarkerPosition = null;
            foreach ($markers as $index => $marker) {
                $markerPosition = strpos($text, $marker);
                if ($markerPosition === false) {
                    unset($markers[$index]);
                    continue;
                }
                if ($closestMarker === null or $markerPosition < $closestMarkerPosition) {
                    $closestMarker = $marker;
                    $closestMarkerIndex = $index;
                    $closestMarkerPosition = $markerPosition;
                }
            }
            # ~
            if ($closestMarker === null or isset($text[$closestMarkerPosition + 1]) === false) {
                $markup .= $text;
                break;
            } else {
                $markup .= substr($text, 0, $closestMarkerPosition);
            }
            $text = substr($text, $closestMarkerPosition);
            # ~
            unset($markers[$closestMarkerIndex]);
            # ~
            switch ($closestMarker) {
                case "  \n":
                    $markup .= '<br />' . "\n";
                    $offset = 3;
                    break;
                case '![':
                case '[':
                    if (strpos($text, ']') and preg_match('/\\[((?:[^][]|(?R))*)\\]/', $text, $matches)) {
                        $element = array('!' => $text[0] === '!', 'text' => $matches[1]);
                        $offset = strlen($matches[0]);
                        if ($element['!']) {
                            $offset++;
                        }
                        $remainingText = substr($text, $offset);
                        if ($remainingText[0] === '(' and preg_match('/\\([ ]*(.*?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*\\)/', $remainingText, $matches)) {
                            $element['link'] = $matches[1];
                            if (isset($matches[2])) {
                                $element['title'] = $matches[2];
                            }
                            $offset += strlen($matches[0]);
                        } elseif ($this->referenceMap) {
                            $reference = $element['text'];
                            if (preg_match('/^\\s*\\[(.*?)\\]/', $remainingText, $matches)) {
                                $reference = $matches[1] === '' ? $element['text'] : $matches[1];
                                $offset += strlen($matches[0]);
                            }
                            $reference = strtolower($reference);
                            if (isset($this->referenceMap[$reference])) {
                                $element['link'] = $this->referenceMap[$reference]['link'];
                                if (isset($this->referenceMap[$reference]['title'])) {
                                    $element['title'] = $this->referenceMap[$reference]['title'];
                                }
                            } else {
                                unset($element);
                            }
                        } else {
                            unset($element);
                        }
                    }
                    if (isset($element)) {
                        $element['link'] = str_replace('&', '&amp;', $element['link']);
                        $element['link'] = str_replace('<', '&lt;', $element['link']);
                        if ($element['!']) {
                            $markup .= '<img alt="' . $element['text'] . '" src="' . $element['link'] . '"';
                            if (isset($element['title'])) {
                                $markup .= ' title="' . $element['title'] . '"';
                            }
                            $markup .= ' />';
                        } else {
                            $element['text'] = $this->parseLine($element['text'], $markers);
                            $markup .= '<a href="' . $element['link'] . '"';
                            if (isset($element['title'])) {
                                $markup .= ' title="' . $element['title'] . '"';
                            }
                            $markup .= '>' . $element['text'] . '</a>';
                        }
                        unset($element);
                    } else {
                        $markup .= $closestMarker;
                        $offset = $closestMarker === '![' ? 2 : 1;
                    }
                    break;
                case '&':
                    if (preg_match('/^&#?\\w+;/', $text, $matches)) {
                        $markup .= $matches[0];
                        $offset = strlen($matches[0]);
                    } else {
                        $markup .= '&amp;';
                        $offset = 1;
                    }
                    break;
                case '*':
                case '_':
                    if ($text[1] === $closestMarker and preg_match(self::$strongRegex[$closestMarker], $text, $matches)) {
                        $markers[$closestMarkerIndex] = $closestMarker;
                        $matches[1] = $this->parseLine($matches[1], $markers);
                        $markup .= '<strong>' . $matches[1] . '</strong>';
                    } elseif (preg_match(self::$emRegex[$closestMarker], $text, $matches)) {
                        $markers[$closestMarkerIndex] = $closestMarker;
                        $matches[1] = $this->parseLine($matches[1], $markers);
                        $markup .= '<em>' . $matches[1] . '</em>';
                    }
                    if (isset($matches) and $matches) {
                        $offset = strlen($matches[0]);
                    } else {
                        $markup .= $closestMarker;
                        $offset = 1;
                    }
                    break;
                case '<':
                    if (strpos($text, '>') !== false) {
                        if ($text[1] === 'h' and preg_match('/^<(https?:[\\/]{2}[^\\s]+?)>/i', $text, $matches)) {
                            $elementUrl = $matches[1];
                            $elementUrl = str_replace('&', '&amp;', $elementUrl);
                            $elementUrl = str_replace('<', '&lt;', $elementUrl);
                            $markup .= '<a href="' . $elementUrl . '">' . $elementUrl . '</a>';
                            $offset = strlen($matches[0]);
                        } elseif (strpos($text, '@') > 1 and preg_match('/<(\\S+?@\\S+?)>/', $text, $matches)) {
                            $markup .= '<a href="mailto:' . $matches[1] . '">' . $matches[1] . '</a>';
                            $offset = strlen($matches[0]);
                        } elseif (preg_match('/^<\\/?\\w.*?>/', $text, $matches)) {
                            $markup .= $matches[0];
                            $offset = strlen($matches[0]);
                        } else {
                            $markup .= '&lt;';
                            $offset = 1;
                        }
                    } else {
                        $markup .= '&lt;';
                        $offset = 1;
                    }
                    break;
                case '\\':
                    if (in_array($text[1], self::$specialCharacters)) {
                        $markup .= $text[1];
                        $offset = 2;
                    } else {
                        $markup .= '\\';
                        $offset = 1;
                    }
                    break;
                case '`':
                    if (preg_match('/^(`+)[ ]*(.+?)[ ]*(?<!`)\\1(?!`)/', $text, $matches)) {
                        $elementText = $matches[2];
                        $elementText = htmlspecialchars($elementText, ENT_NOQUOTES, 'UTF-8');
                        $markup .= '<code>' . $elementText . '</code>';
                        $offset = strlen($matches[0]);
                    } else {
                        $markup .= '`';
                        $offset = 1;
                    }
                    break;
                case 'http':
                    if (preg_match('/^https?:[\\/]{2}[^\\s]+\\b\\/*/ui', $text, $matches)) {
                        $elementUrl = $matches[0];
                        $elementUrl = str_replace('&', '&amp;', $elementUrl);
                        $elementUrl = str_replace('<', '&lt;', $elementUrl);
                        $markup .= '<a href="' . $elementUrl . '">' . $elementUrl . '</a>';
                        $offset = strlen($matches[0]);
                    } else {
                        $markup .= 'http';
                        $offset = 4;
                    }
                    break;
                case '~~':
                    if (preg_match('/^~~(?=\\S)(.+?)(?<=\\S)~~/', $text, $matches)) {
                        $matches[1] = $this->parseLine($matches[1], $markers);
                        $markup .= '<del>' . $matches[1] . '</del>';
                        $offset = strlen($matches[0]);
                    } else {
                        $markup .= '~~';
                        $offset = 2;
                    }
                    break;
            }
            if (isset($offset)) {
                $text = substr($text, $offset);
            }
            $markers[$closestMarkerIndex] = $closestMarker;
        }
        return $markup;
    }