init
This commit is contained in:
45
vendor/cebe/markdown/inline/CodeTrait.php
vendored
Normal file
45
vendor/cebe/markdown/inline/CodeTrait.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2014 Carsten Brandt
|
||||
* @license https://github.com/cebe/markdown/blob/master/LICENSE
|
||||
* @link https://github.com/cebe/markdown#readme
|
||||
*/
|
||||
|
||||
namespace cebe\markdown\inline;
|
||||
|
||||
/**
|
||||
* Adds inline code elements
|
||||
*/
|
||||
trait CodeTrait
|
||||
{
|
||||
/**
|
||||
* Parses an inline code span `` ` ``.
|
||||
* @marker `
|
||||
*/
|
||||
protected function parseInlineCode($text)
|
||||
{
|
||||
if (preg_match('/^(``+)\s(.+?)\s\1/s', $text, $matches)) { // code with enclosed backtick
|
||||
return [
|
||||
[
|
||||
'inlineCode',
|
||||
$matches[2],
|
||||
],
|
||||
strlen($matches[0])
|
||||
];
|
||||
} elseif (preg_match('/^`(.+?)`/s', $text, $matches)) {
|
||||
return [
|
||||
[
|
||||
'inlineCode',
|
||||
$matches[1],
|
||||
],
|
||||
strlen($matches[0])
|
||||
];
|
||||
}
|
||||
return [['text', $text[0]], 1];
|
||||
}
|
||||
|
||||
protected function renderInlineCode($block)
|
||||
{
|
||||
return '<code>' . htmlspecialchars($block[1], ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</code>';
|
||||
}
|
||||
}
|
||||
80
vendor/cebe/markdown/inline/EmphStrongTrait.php
vendored
Normal file
80
vendor/cebe/markdown/inline/EmphStrongTrait.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2014 Carsten Brandt
|
||||
* @license https://github.com/cebe/markdown/blob/master/LICENSE
|
||||
* @link https://github.com/cebe/markdown#readme
|
||||
*/
|
||||
|
||||
namespace cebe\markdown\inline;
|
||||
|
||||
/**
|
||||
* Adds inline emphasizes and strong elements
|
||||
*/
|
||||
trait EmphStrongTrait
|
||||
{
|
||||
/**
|
||||
* Parses empathized and strong elements.
|
||||
* @marker _
|
||||
* @marker *
|
||||
*/
|
||||
protected function parseEmphStrong($text)
|
||||
{
|
||||
$marker = $text[0];
|
||||
|
||||
if (!isset($text[1])) {
|
||||
return [['text', $text[0]], 1];
|
||||
}
|
||||
|
||||
if ($marker == $text[1]) { // strong
|
||||
// work around a PHP bug that crashes with a segfault on too much regex backtrack
|
||||
// check whether the end marker exists in the text
|
||||
// https://github.com/erusev/parsedown/issues/443
|
||||
// https://bugs.php.net/bug.php?id=45735
|
||||
if (strpos($text, $marker . $marker, 2) === false) {
|
||||
return [['text', $text[0] . $text[1]], 2];
|
||||
}
|
||||
|
||||
if ($marker == '*' && preg_match('/^[*]{2}((?:[^*]|[*][^*]*[*])+?)[*]{2}(?![*]{2})/s', $text, $matches) ||
|
||||
$marker == '_' && preg_match('/^__((?:[^_]|_[^_]*_)+?)__(?!__)/us', $text, $matches)) {
|
||||
|
||||
return [
|
||||
[
|
||||
'strong',
|
||||
$this->parseInline($matches[1]),
|
||||
],
|
||||
strlen($matches[0])
|
||||
];
|
||||
}
|
||||
} else { // emph
|
||||
// work around a PHP bug that crashes with a segfault on too much regex backtrack
|
||||
// check whether the end marker exists in the text
|
||||
// https://github.com/erusev/parsedown/issues/443
|
||||
// https://bugs.php.net/bug.php?id=45735
|
||||
if (strpos($text, $marker, 1) === false) {
|
||||
return [['text', $text[0]], 1];
|
||||
}
|
||||
|
||||
if ($marker == '*' && preg_match('/^[*]((?:[^*]|[*][*][^*]+?[*][*])+?)[*](?![*][^*])/s', $text, $matches) ||
|
||||
$marker == '_' && preg_match('/^_((?:[^_]|__[^_]*__)+?)_(?!_[^_])\b/us', $text, $matches)) {
|
||||
return [
|
||||
[
|
||||
'emph',
|
||||
$this->parseInline($matches[1]),
|
||||
],
|
||||
strlen($matches[0])
|
||||
];
|
||||
}
|
||||
}
|
||||
return [['text', $text[0]], 1];
|
||||
}
|
||||
|
||||
protected function renderStrong($block)
|
||||
{
|
||||
return '<strong>' . $this->renderAbsy($block[1]) . '</strong>';
|
||||
}
|
||||
|
||||
protected function renderEmph($block)
|
||||
{
|
||||
return '<em>' . $this->renderAbsy($block[1]) . '</em>';
|
||||
}
|
||||
}
|
||||
278
vendor/cebe/markdown/inline/LinkTrait.php
vendored
Normal file
278
vendor/cebe/markdown/inline/LinkTrait.php
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2014 Carsten Brandt
|
||||
* @license https://github.com/cebe/markdown/blob/master/LICENSE
|
||||
* @link https://github.com/cebe/markdown#readme
|
||||
*/
|
||||
|
||||
namespace cebe\markdown\inline;
|
||||
|
||||
// work around https://github.com/facebook/hhvm/issues/1120
|
||||
defined('ENT_HTML401') || define('ENT_HTML401', 0);
|
||||
|
||||
/**
|
||||
* Addes links and images as well as url markers.
|
||||
*
|
||||
* This trait conflicts with the HtmlTrait. If both are used together,
|
||||
* you have to define a resolution, by defining the HtmlTrait::parseInlineHtml
|
||||
* as private so it is not used directly:
|
||||
*
|
||||
* ```php
|
||||
* use block\HtmlTrait {
|
||||
* parseInlineHtml as private parseInlineHtml;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If the method exists it is called internally by this trait.
|
||||
*
|
||||
* Also make sure to reset references on prepare():
|
||||
*
|
||||
* ```php
|
||||
* protected function prepare()
|
||||
* {
|
||||
* // reset references
|
||||
* $this->references = [];
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
trait LinkTrait
|
||||
{
|
||||
/**
|
||||
* @var array a list of defined references in this document.
|
||||
*/
|
||||
protected $references = [];
|
||||
|
||||
/**
|
||||
* Remove backslash from escaped characters
|
||||
* @param $text
|
||||
* @return string
|
||||
*/
|
||||
protected function replaceEscape($text)
|
||||
{
|
||||
$strtr = [];
|
||||
foreach($this->escapeCharacters as $char) {
|
||||
$strtr["\\$char"] = $char;
|
||||
}
|
||||
return strtr($text, $strtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a link indicated by `[`.
|
||||
* @marker [
|
||||
*/
|
||||
protected function parseLink($markdown)
|
||||
{
|
||||
if (!in_array('parseLink', array_slice($this->context, 1)) && ($parts = $this->parseLinkOrImage($markdown)) !== false) {
|
||||
list($text, $url, $title, $offset, $key) = $parts;
|
||||
return [
|
||||
[
|
||||
'link',
|
||||
'text' => $this->parseInline($text),
|
||||
'url' => $url,
|
||||
'title' => $title,
|
||||
'refkey' => $key,
|
||||
'orig' => substr($markdown, 0, $offset),
|
||||
],
|
||||
$offset
|
||||
];
|
||||
} else {
|
||||
// remove all starting [ markers to avoid next one to be parsed as link
|
||||
$result = '[';
|
||||
$i = 1;
|
||||
while (isset($markdown[$i]) && $markdown[$i] == '[') {
|
||||
$result .= '[';
|
||||
$i++;
|
||||
}
|
||||
return [['text', $result], $i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an image indicated by `![`.
|
||||
* @marker ![
|
||||
*/
|
||||
protected function parseImage($markdown)
|
||||
{
|
||||
if (($parts = $this->parseLinkOrImage(substr($markdown, 1))) !== false) {
|
||||
list($text, $url, $title, $offset, $key) = $parts;
|
||||
|
||||
return [
|
||||
[
|
||||
'image',
|
||||
'text' => $text,
|
||||
'url' => $url,
|
||||
'title' => $title,
|
||||
'refkey' => $key,
|
||||
'orig' => substr($markdown, 0, $offset + 1),
|
||||
],
|
||||
$offset + 1
|
||||
];
|
||||
} else {
|
||||
// remove all starting [ markers to avoid next one to be parsed as link
|
||||
$result = '!';
|
||||
$i = 1;
|
||||
while (isset($markdown[$i]) && $markdown[$i] == '[') {
|
||||
$result .= '[';
|
||||
$i++;
|
||||
}
|
||||
return [['text', $result], $i];
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseLinkOrImage($markdown)
|
||||
{
|
||||
if (strpos($markdown, ']') !== false && preg_match('/\[((?>[^\]\[]+|(?R))*)\]/', $markdown, $textMatches)) { // TODO improve bracket regex
|
||||
$text = $textMatches[1];
|
||||
$offset = strlen($textMatches[0]);
|
||||
$markdown = substr($markdown, $offset);
|
||||
|
||||
$pattern = <<<REGEXP
|
||||
/(?(R) # in case of recursion match parentheses
|
||||
\(((?>[^\s()]+)|(?R))*\)
|
||||
| # else match a link with title
|
||||
^\(\s*(((?>[^\s()]+)|(?R))*)(\s+"(.*?)")?\s*\)
|
||||
)/x
|
||||
REGEXP;
|
||||
if (preg_match($pattern, $markdown, $refMatches)) {
|
||||
// inline link
|
||||
return [
|
||||
$text,
|
||||
isset($refMatches[2]) ? $this->replaceEscape($refMatches[2]) : '', // url
|
||||
empty($refMatches[5]) ? null: $refMatches[5], // title
|
||||
$offset + strlen($refMatches[0]), // offset
|
||||
null, // reference key
|
||||
];
|
||||
} elseif (preg_match('/^([ \n]?\[(.*?)\])?/s', $markdown, $refMatches)) {
|
||||
// reference style link
|
||||
if (empty($refMatches[2])) {
|
||||
$key = strtolower($text);
|
||||
} else {
|
||||
$key = strtolower($refMatches[2]);
|
||||
}
|
||||
return [
|
||||
$text,
|
||||
null, // url
|
||||
null, // title
|
||||
$offset + strlen($refMatches[0]), // offset
|
||||
$key,
|
||||
];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses inline HTML.
|
||||
* @marker <
|
||||
*/
|
||||
protected function parseLt($text)
|
||||
{
|
||||
if (strpos($text, '>') !== false) {
|
||||
if (!in_array('parseLink', $this->context)) { // do not allow links in links
|
||||
if (preg_match('/^<([^\s]*?@[^\s]*?\.\w+?)>/', $text, $matches)) {
|
||||
// email address
|
||||
return [
|
||||
['email', $this->replaceEscape($matches[1])],
|
||||
strlen($matches[0])
|
||||
];
|
||||
} elseif (preg_match('/^<([a-z]{3,}:\/\/[^\s]+?)>/', $text, $matches)) {
|
||||
// URL
|
||||
return [
|
||||
['url', $this->replaceEscape($matches[1])],
|
||||
strlen($matches[0])
|
||||
];
|
||||
}
|
||||
}
|
||||
// try inline HTML if it was neither a URL nor email if HtmlTrait is included.
|
||||
if (method_exists($this, 'parseInlineHtml')) {
|
||||
return $this->parseInlineHtml($text);
|
||||
}
|
||||
}
|
||||
return [['text', '<'], 1];
|
||||
}
|
||||
|
||||
protected function renderEmail($block)
|
||||
{
|
||||
$email = htmlspecialchars($block[1], ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
return "<a href=\"mailto:$email\">$email</a>";
|
||||
}
|
||||
|
||||
protected function renderUrl($block)
|
||||
{
|
||||
$url = htmlspecialchars($block[1], ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$decodedUrl = urldecode($block[1]);
|
||||
$secureUrlText = preg_match('//u', $decodedUrl) ? $decodedUrl : $block[1];
|
||||
$text = htmlspecialchars($secureUrlText, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
return "<a href=\"$url\">$text</a>";
|
||||
}
|
||||
|
||||
protected function lookupReference($key)
|
||||
{
|
||||
$normalizedKey = preg_replace('/\s+/', ' ', $key);
|
||||
if (isset($this->references[$key]) || isset($this->references[$key = $normalizedKey])) {
|
||||
return $this->references[$key];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function renderLink($block)
|
||||
{
|
||||
if (isset($block['refkey'])) {
|
||||
if (($ref = $this->lookupReference($block['refkey'])) !== false) {
|
||||
$block = array_merge($block, $ref);
|
||||
} else {
|
||||
return $block['orig'];
|
||||
}
|
||||
}
|
||||
return '<a href="' . htmlspecialchars($block['url'], ENT_COMPAT | ENT_HTML401, 'UTF-8') . '"'
|
||||
. (empty($block['title']) ? '' : ' title="' . htmlspecialchars($block['title'], ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE, 'UTF-8') . '"')
|
||||
. '>' . $this->renderAbsy($block['text']) . '</a>';
|
||||
}
|
||||
|
||||
protected function renderImage($block)
|
||||
{
|
||||
if (isset($block['refkey'])) {
|
||||
if (($ref = $this->lookupReference($block['refkey'])) !== false) {
|
||||
$block = array_merge($block, $ref);
|
||||
} else {
|
||||
return $block['orig'];
|
||||
}
|
||||
}
|
||||
return '<img src="' . htmlspecialchars($block['url'], ENT_COMPAT | ENT_HTML401, 'UTF-8') . '"'
|
||||
. ' alt="' . htmlspecialchars($block['text'], ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE, 'UTF-8') . '"'
|
||||
. (empty($block['title']) ? '' : ' title="' . htmlspecialchars($block['title'], ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE, 'UTF-8') . '"')
|
||||
. ($this->html5 ? '>' : ' />');
|
||||
}
|
||||
|
||||
// references
|
||||
|
||||
protected function identifyReference($line)
|
||||
{
|
||||
return ($line[0] === ' ' || $line[0] === '[') && preg_match('/^ {0,3}\[(.+?)\]:\s*([^\s]+?)(?:\s+[\'"](.+?)[\'"])?\s*$/', $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume link references
|
||||
*/
|
||||
protected function consumeReference($lines, $current)
|
||||
{
|
||||
while (isset($lines[$current]) && preg_match('/^ {0,3}\[(.+?)\]:\s*(.+?)(?:\s+[\(\'"](.+?)[\)\'"])?\s*$/', $lines[$current], $matches)) {
|
||||
$label = strtolower($matches[1]);
|
||||
|
||||
$this->references[$label] = [
|
||||
'url' => $this->replaceEscape($matches[2]),
|
||||
];
|
||||
if (isset($matches[3])) {
|
||||
$this->references[$label]['title'] = $matches[3];
|
||||
} else {
|
||||
// title may be on the next line
|
||||
if (isset($lines[$current + 1]) && preg_match('/^\s+[\(\'"](.+?)[\)\'"]\s*$/', $lines[$current + 1], $matches)) {
|
||||
$this->references[$label]['title'] = $matches[1];
|
||||
$current++;
|
||||
}
|
||||
}
|
||||
$current++;
|
||||
}
|
||||
return [false, --$current];
|
||||
}
|
||||
}
|
||||
37
vendor/cebe/markdown/inline/StrikeoutTrait.php
vendored
Normal file
37
vendor/cebe/markdown/inline/StrikeoutTrait.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2014 Carsten Brandt
|
||||
* @license https://github.com/cebe/markdown/blob/master/LICENSE
|
||||
* @link https://github.com/cebe/markdown#readme
|
||||
*/
|
||||
|
||||
namespace cebe\markdown\inline;
|
||||
|
||||
/**
|
||||
* Adds strikeout inline elements
|
||||
*/
|
||||
trait StrikeoutTrait
|
||||
{
|
||||
/**
|
||||
* Parses the strikethrough feature.
|
||||
* @marker ~~
|
||||
*/
|
||||
protected function parseStrike($markdown)
|
||||
{
|
||||
if (preg_match('/^~~(.+?)~~/', $markdown, $matches)) {
|
||||
return [
|
||||
[
|
||||
'strike',
|
||||
$this->parseInline($matches[1])
|
||||
],
|
||||
strlen($matches[0])
|
||||
];
|
||||
}
|
||||
return [['text', $markdown[0] . $markdown[1]], 2];
|
||||
}
|
||||
|
||||
protected function renderStrike($block)
|
||||
{
|
||||
return '<del>' . $this->renderAbsy($block[1]) . '</del>';
|
||||
}
|
||||
}
|
||||
50
vendor/cebe/markdown/inline/UrlLinkTrait.php
vendored
Normal file
50
vendor/cebe/markdown/inline/UrlLinkTrait.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2014 Carsten Brandt
|
||||
* @license https://github.com/cebe/markdown/blob/master/LICENSE
|
||||
* @link https://github.com/cebe/markdown#readme
|
||||
*/
|
||||
|
||||
namespace cebe\markdown\inline;
|
||||
|
||||
// work around https://github.com/facebook/hhvm/issues/1120
|
||||
defined('ENT_HTML401') || define('ENT_HTML401', 0);
|
||||
|
||||
/**
|
||||
* Adds auto linking for URLs
|
||||
*/
|
||||
trait UrlLinkTrait
|
||||
{
|
||||
/**
|
||||
* Parses urls and adds auto linking feature.
|
||||
* @marker http
|
||||
* @marker ftp
|
||||
*/
|
||||
protected function parseUrl($markdown)
|
||||
{
|
||||
$pattern = <<<REGEXP
|
||||
/(?(R) # in case of recursion match parentheses
|
||||
\(((?>[^\s()]+)|(?R))*\)
|
||||
| # else match a link with title
|
||||
^(https?|ftp):\/\/(([^\s()]+)|(?R))+(?<![\.,:;\'"!\?\s])
|
||||
)/x
|
||||
REGEXP;
|
||||
|
||||
if (!in_array('parseLink', $this->context) && preg_match($pattern, $markdown, $matches)) {
|
||||
return [
|
||||
['autoUrl', $matches[0]],
|
||||
strlen($matches[0])
|
||||
];
|
||||
}
|
||||
return [['text', substr($markdown, 0, 4)], 4];
|
||||
}
|
||||
|
||||
protected function renderAutoUrl($block)
|
||||
{
|
||||
$href = htmlspecialchars($block[1], ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$decodedUrl = urldecode($block[1]);
|
||||
$secureUrlText = preg_match('//u', $decodedUrl) ? $decodedUrl : $block[1];
|
||||
$text = htmlspecialchars($secureUrlText, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
return "<a href=\"$href\">$text</a>";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user