"Parsedown", "version" => "0.3", "author" => "Johnny Broadway, Emanuil Rusev & Starbeamrainbowlabs", "description" => "An upgraded parser based on Emanuil Rusev's Parsedown Extra PHP library (https://github.com/erusev/parsedown-extra), which is licensed MIT. Please be careful, as this module adds a some weight to your installation, and also requires write access to the disk on first load.", "id" => "parser-parsedown", "code" => function() { $parser = new PeppermintParsedown(); $parser->setInternalLinkBase("?page=%s"); add_parser("parsedown", function($source) use ($parser) { $result = $parser->text($source); return $result; }); } ]); /*** Parsedown versions *** * Parsedown Core: 1.6.0 * * Parsedown Extra: 0.7.0 * **************************/ $env->parsedown_paths = new stdClass(); $env->parsedown_paths->parsedown = "https://cdn.rawgit.com/erusev/parsedown/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7/Parsedown.php"; $env->parsedown_paths->parsedown_extra = "https://cdn.rawgit.com/erusev/parsedown-extra/11a44e076d02ffcc4021713398a60cd73f78b6f5/ParsedownExtra.php"; // Download parsedown and parsedown extra if they don't already exist if(!file_exists("./Parsedown.php") || filesize("./Parsedown.php") === 0) file_put_contents("./Parsedown.php", fopen($env->parsedown_paths->parsedown, "r")); if(!file_exists("./ParsedownExtra.php") || filesize("./ParsedownExtra.php") === 0) file_put_contents("./ParsedownExtra.php", fopen($env->parsedown_paths->parsedown_extra, "r")); require_once("./Parsedown.php"); require_once("./ParsedownExtra.php"); /* * ██████ █████ ██████ ███████ ███████ ██████ ██████ ██ ██ ███ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ * ██████ ███████ ██████ ███████ █████ ██ ██ ██ ██ ██ █ ██ ██ ██ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ ██ ██ ██ * ██ ██ ██ ██ ██ ███████ ███████ ██████ ██████ ███ ███ ██ ████ * * ███████ ██ ██ ████████ ███████ ███ ██ ███████ ██ ██████ ███ ██ ███████ * ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ████ ██ ██ * █████ ███ ██ █████ ██ ██ ██ ███████ ██ ██ ██ ██ ██ ██ ███████ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ * ███████ ██ ██ ██ ███████ ██ ████ ███████ ██ ██████ ██ ████ ███████ */ class PeppermintParsedown extends ParsedownExtra { private $internalLinkBase = "./%s"; function __construct() { // Prioritise our internal link parsing over the regular link parsing array_unshift($this->InlineTypes["["], "InternalLink"); // Prioritise our image parser over the regular image parser array_unshift($this->InlineTypes["!"], "ExtendedImage"); //$this->inlineMarkerList .= "{"; } protected function inlineInternalLink($fragment) { if(preg_match('/^\[\[(.*)\]\]/', $fragment["text"], $matches)) { $display = $linkPage = $matches[1]; if(strpos($matches[1], "|")) { // We have a bar character $parts = explode("|", $matches[1], 2); $linkPage = $parts[0]; $display = $parts[1]; } // Construct the full url $linkUrl = str_replace( "%s", rawurlencode($linkPage), $this->internalLinkBase ); return [ "extent" => strlen($matches[0]), "element" => [ "name" => "a", "text" => $display, "attributes" => [ "href" => $linkUrl ] ] ]; } return; } protected function inlineExtendedImage($fragment) { if(preg_match('/^!\[(.*)\]\(([^ |)]+)\s*\|([^|)]*)(?:\|([^)]*))?\)/', $fragment["text"], $matches)) { /* * 0 - Everything * 1 - Alt text * 2 - Url * 3 - First param * 4 - Second Param (optional) */ var_dump($matches); $altText = $matches[1]; $imageUrl = $matches[2]; $param1 = strtolower(trim($matches[3])); $param2 = empty($matches[4]) ? false : strtolower(trim($matches[4])); $floatDirection = false; $imageSize = false; if($this->isFloatValue($param1)) { $floatDirection = $param1; $imageSize = $this->parseSizeSpec($param2); } else if($this->isFloatValue($param2)) { $floatDirection = $param2; $imageSize = $this->parseSizeSpec($param1); } else { $imageSize = $this->parseSizeSpec($param1); } // If they are both invalid then something very strange is going on // Let the built in parsedown image handler deal with it if($imageSize === false && $floatDirection === false) return; $style = ""; if($imageSize !== false) $style .= " max-width: " . $imageSize["x"] . "; max-height: " . $imageSize["y"] . ";"; if($floatDirection) $style .= " float: $floatDirection;"; return [ "extent" => strlen($matches[0]), "element" => [ "name" => "img", "attributes" => [ "src" => $imageUrl, "alt" => $altText, "style" => trim($style) ] ] ]; } } private function isFloatValue($value) { return in_array(strtolower($value), [ "left", "right" ]); } private function parseSizeSpec($text) { if(strpos($text, "x") === false) return false; $parts = explode("x", $text, 2); if(count($parts) != 2) return false; array_map("trim", $parts); array_map("intval", $parts); if(in_array(0, $parts)) return false; return [ "x" => $parts[0], "y" => $parts[1] ]; } /** * Sets the base url to be used for internal links. '%s' will be replaced * with a URL encoded version of the page name. * @param string $url The url to use when parsing internal links. */ public function setInternalLinkBase($url) { $this->internalLinkBase = $url; } } ?>