2013-10-19 15:10:28 +02:00
|
|
|
<?php
|
|
|
|
class CustomMarkdown extends \Michelf\Markdown
|
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
protected $simple = false;
|
|
|
|
|
|
|
|
public function __construct($simple = false)
|
2013-10-19 15:10:28 +02:00
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
$this->simple = $simple;
|
2013-10-19 15:10:28 +02:00
|
|
|
$this->no_markup = true;
|
2014-01-14 23:20:47 +01:00
|
|
|
$this->span_gamut += ['doSpoilers' => 71];
|
2013-11-21 15:16:27 +01:00
|
|
|
$this->span_gamut += ['doSearchPermalinks' => 72];
|
2013-11-18 00:38:33 +01:00
|
|
|
$this->span_gamut += ['doStrike' => 6];
|
2013-11-18 11:20:02 +01:00
|
|
|
$this->span_gamut += ['doUsers' => 7];
|
2013-10-19 15:10:28 +02:00
|
|
|
$this->span_gamut += ['doPosts' => 8];
|
|
|
|
$this->span_gamut += ['doTags' => 9];
|
2013-10-26 12:08:42 +02:00
|
|
|
$this->span_gamut += ['doAutoLinks2' => 29];
|
2013-11-17 14:20:59 +01:00
|
|
|
|
|
|
|
//fix italics/bold in the middle of sentence
|
|
|
|
$prop = ['em_relist', 'strong_relist', 'em_strong_relist'];
|
|
|
|
for ($i = 0; $i < 3; $i ++)
|
|
|
|
{
|
|
|
|
$this->{$prop[$i]}[''] = '(?:(?<!\*)' . str_repeat('\*', $i + 1) . '(?!\*)|(?<![a-zA-Z0-9_])' . str_repeat('_', $i + 1) . '(?!_))(?=\S|$)(?![\.,:;]\s)';
|
|
|
|
$this->{$prop[$i]}[str_repeat('*', $i + 1)] = '(?<=\S|^)(?<!\*)' . str_repeat('\*', $i + 1) . '(?!\*)';
|
|
|
|
$this->{$prop[$i]}[str_repeat('_', $i + 1)] = '(?<=\S|^)(?<!_)' . str_repeat('_', $i + 1) . '(?![a-zA-Z0-9_])';
|
|
|
|
}
|
|
|
|
|
2013-10-19 15:10:28 +02:00
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
2013-11-23 20:00:02 +01:00
|
|
|
protected function formParagraphs($text)
|
|
|
|
{
|
|
|
|
if ($this->simple)
|
|
|
|
{
|
|
|
|
$text = preg_replace('/\A\n+|\n+\z/', '', $text);
|
|
|
|
$grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
|
|
|
|
foreach ($grafs as $key => $value)
|
|
|
|
{
|
|
|
|
if (!preg_match('/^B\x1A[0-9]+B$/', $value))
|
|
|
|
{
|
|
|
|
$value = $this->runSpanGamut($value);
|
|
|
|
$grafs[$key] = $this->unhash($value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$grafs[$key] = $this->html_hashes[$value];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return implode("\n\n", $grafs);
|
|
|
|
}
|
|
|
|
return parent::formParagraphs($text);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function simpleTransform($text)
|
|
|
|
{
|
|
|
|
$parser = new self(true);
|
|
|
|
return $parser->transform($text);
|
|
|
|
}
|
|
|
|
|
2013-10-26 12:08:42 +02:00
|
|
|
protected function doAutoLinks2($text)
|
|
|
|
{
|
2013-11-25 11:50:34 +01:00
|
|
|
$text = preg_replace_callback('{(?<!<)((https?|ftp):[^\'"><\s(){}]+)}i', [&$this, '_doAutoLinks_url_callback'], $text);
|
|
|
|
$text = preg_replace_callback('{(?<![^\s\(\)\[\]])(www\.[^\'"><\s(){}]+)}i', [&$this, '_doAutoLinks_url_callback'], $text);
|
2013-10-26 12:08:42 +02:00
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function _doAnchors_inline_callback($matches)
|
|
|
|
{
|
|
|
|
if ($matches[3] == '')
|
|
|
|
$url = &$matches[4];
|
|
|
|
else
|
|
|
|
$url = &$matches[3];
|
|
|
|
if (!preg_match('/^((https?|ftp):|)\/\//', $url))
|
|
|
|
$url = 'http://' . $url;
|
|
|
|
return parent::_doAnchors_inline_callback($matches);
|
|
|
|
}
|
|
|
|
|
2013-12-08 12:12:45 +01:00
|
|
|
protected function _doCodeBlocks_callback($matches) {
|
|
|
|
$codeblock = $matches[1];
|
|
|
|
|
|
|
|
$codeblock = $this->outdent($codeblock);
|
|
|
|
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
|
|
|
|
|
|
|
|
$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
|
|
|
|
$codeblock = preg_replace('/\n/', '<br/>', $codeblock);
|
|
|
|
$codeblock = preg_replace('/\t/', '&tab;', $codeblock);
|
|
|
|
$codeblock = preg_replace('/ /', ' ', $codeblock);
|
|
|
|
|
|
|
|
$codeblock = "<pre><code>$codeblock\n</code></pre>";
|
|
|
|
return "\n\n".$this->hashBlock($codeblock)."\n\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-10-19 15:10:28 +02:00
|
|
|
protected function doHardBreaks($text)
|
|
|
|
{
|
2013-11-21 14:56:45 +01:00
|
|
|
return preg_replace_callback('/\n(?=[\[\]\(\)\w])/', [&$this, '_doHardBreaks_callback'], $text);
|
2013-10-19 15:10:28 +02:00
|
|
|
}
|
|
|
|
|
2013-11-18 00:38:33 +01:00
|
|
|
protected function doStrike($text)
|
|
|
|
{
|
|
|
|
return preg_replace_callback('{(~~|---)([^~]+)\1}', function($x)
|
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
return $this->hashPart('<del>' . $x[2] . '</del>');
|
2013-11-18 00:38:33 +01:00
|
|
|
}, $text);
|
|
|
|
}
|
|
|
|
|
2013-10-19 15:10:28 +02:00
|
|
|
protected function doSpoilers($text)
|
|
|
|
{
|
|
|
|
if (is_array($text))
|
2013-11-21 22:47:55 +01:00
|
|
|
$text = $this->hashBlock('<span class="spoiler">') . $this->runSpanGamut($text[1]) . $this->hashBlock('</span>');
|
2013-10-19 15:10:28 +02:00
|
|
|
return preg_replace_callback('{\[spoiler\]((?:[^\[]|\[(?!\/?spoiler\])|(?R))+)\[\/spoiler\]}is', [__CLASS__, 'doSpoilers'], $text);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function doPosts($text)
|
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
$link = \Chibi\UrlHelper::route('post', 'view', ['id' => '_post_']);
|
|
|
|
return preg_replace_callback('/(?:(?<![^\s\(\)\[\]]))@(\d+)/', function($x) use ($link)
|
2013-10-19 15:10:28 +02:00
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
return $this->hashPart('<a href="' . str_replace('_post_', $x[1], $link) . '">' . $x[0] . '</a>');
|
2013-10-19 15:10:28 +02:00
|
|
|
}, $text);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function doTags($text)
|
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
$link = \Chibi\UrlHelper::route('post', 'list', ['query' => '_query_']);
|
|
|
|
return preg_replace_callback('/(?:(?<![^\s\(\)\[\]]))#([a-zA-Z0-9_-]+)/', function($x) use ($link)
|
2013-10-19 15:10:28 +02:00
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
return $this->hashPart('<a href="' . str_replace('_query_', $x[1], $link) . '">' . $x[0] . '</a>');
|
2013-10-19 15:10:28 +02:00
|
|
|
}, $text);
|
|
|
|
}
|
2013-11-17 14:39:50 +01:00
|
|
|
|
|
|
|
protected function doUsers($text)
|
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
$link = \Chibi\UrlHelper::route('user', 'view', ['name' => '_name_']);
|
|
|
|
return preg_replace_callback('/(?:(?<![^\s\(\)\[\]]))\+([a-zA-Z0-9_-]+)/', function($x) use ($link)
|
2013-11-17 14:39:50 +01:00
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
return $this->hashPart('<a href="' . str_replace('_name_', $x[1], $link) . '">' . $x[0] . '</a>');
|
2013-11-17 14:39:50 +01:00
|
|
|
}, $text);
|
|
|
|
}
|
2013-11-21 15:16:27 +01:00
|
|
|
|
|
|
|
protected function doSearchPermalinks($text)
|
|
|
|
{
|
2013-11-23 20:00:02 +01:00
|
|
|
$link = \Chibi\UrlHelper::route('post', 'list', ['query' => '_query_']);
|
|
|
|
return preg_replace_callback('{\[search\]((?:[^\[]|\[(?!\/?search\]))+)\[\/search\]}is', function($x) use ($link)
|
2013-11-21 15:16:27 +01:00
|
|
|
{
|
2013-11-27 17:42:26 +01:00
|
|
|
return $this->hashPart('<a href="' . str_replace('_query_', urlencode($x[1]), $link) . '">' . $x[1] . '</a>');
|
2013-11-21 15:16:27 +01:00
|
|
|
}, $text);
|
|
|
|
}
|
2013-10-19 15:10:28 +02:00
|
|
|
}
|