["onMarkdownInitialized", 0], ]; } public function onMarkdownInitialized(Event $event) { $markdown = $event["markdown"]; $config = $this->grav["config"]->get("plugins.".$this->name); // TODO: Once Grav requires Parsedown 1.8: // - $Element["name"] is no longer required, so remove redundant spans // - $Element["handler"] changes for extents with Markdown inside // - Do arrows starting with "<" work in that version? $arrows = $config["arrows"]; // Enable arrows (before dashes to avoid conflict) if ($arrows["enabled"]) { $this->thin_arrows = explode(",", $arrows["thin_arrows"]) ?: ["→","←","⟶","⟵"]; $this->thick_arrows = explode(",", $arrows["thick_arrows"]) ?: ["⇒","⇐","⟹","⟸"]; // Add inline types $markdown->addInlineType("-", "TypographyArrowSingleRight"); $markdown->addInlineType("=", "TypographyArrowDoubleRight"); //$markdown->addInlineType(">", "TypographyArrowBothLeft"); // Add function to handle inline type $markdown->inlineTypographyArrowSingleRight = function($excerpt) { if (preg_match("/^(--?>)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => strlen($matches[1]) == 2 ? $this->thin_arrows[0] : $this->thin_arrows[2 % count($this->thin_arrows)], // single right arrow (long arrow: ⟶) "attributes" => [ "class" => "typography-arrow" ] ), ); } elseif (preg_match("/^(--?<)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => strlen($matches[1]) == 2 ? $this->thin_arrows[1] : $this->thin_arrows[3 % count($this->thin_arrows)], // single left arrow (long arrow: ⟵) "attributes" => [ "class" => "typography-arrow" ] ), ); } }; $markdown->inlineTypographyArrowDoubleRight = function($excerpt) { if (preg_match("/^(==?>)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => strlen($matches[1]) == 2 ? $this->thick_arrows[0] : $this->thick_arrows[2 % count($this->thick_arrows)], // fat right arrow "attributes" => [ "class" => "typography-arrow" ] ), ); } elseif (preg_match("/^(==?<)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => strlen($matches[1]) == 2 ? $this->thick_arrows[1] : $this->thick_arrows[3 % count($this->thick_arrows)], // fat left arrow "attributes" => [ "class" => "typography-arrow" ] ), ); } }; // TODO: Doesn't seem to work at the moment!? /*$markdown->inlineTypographyArrowBothLeft = function($excerpt) { $this->grav["debugger"]->addMessage($excerpt); if (preg_match("/^(.--?)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => "←", // thin left arrow "attributes" => [ "class" => "typography-arrow" ] ), ); } elseif (preg_match("/^(.==?)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => "⇦", // fat left arrow "attributes" => [ "class" => "typography-arrow" ] ), ); } };*/ } // Enable dashes if ($config["dashes"]) { // Add inline type $markdown->addInlineType("-", "TypographyDash"); // Add function to handle inline type $markdown->inlineTypographyDash = function($excerpt) { if (preg_match("/-/", $excerpt["text"], $matches) && preg_match("/ (-) /", $excerpt["context"], $matches)) { return array( "extent" => 1, "element" => array( "name" => "span", "text" => "–", // en dash ), ); } elseif (preg_match("/^(---)/", $excerpt["text"], $matches)) { return array( "extent" => 3, "element" => array( "name" => "span", "text" => "—", // em dash ), ); } elseif (preg_match("/^(--)/", $excerpt["text"], $matches)) { return array( "extent" => 2, "element" => array( "name" => "span", "text" => "–", // en dash ), ); } }; } // Enable smart-quotes if ($config["smart_quotes"]) { // Add inline types $markdown->addInlineType('"', "TypographyDoubleQuote"); $markdown->addInlineType("'", "TypographySingleQuote"); // Add function to handle double quotes $markdown->inlineTypographyDoubleQuote = function($excerpt) { if (preg_match_all('/^"([\s\S]*?)"/', $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[0][0]), "element" => array( "name" => "span", "text" => "“".$matches[1][0]."”", // double-quotes "handler" => "line", ), ); } elseif (preg_match('/^\s?"/', $excerpt["context"], $matches)) { return array( "extent" => strlen($excerpt["text"]), "element" => array( "name" => "span", "text" => "“" . substr($excerpt["text"], 1), // Lonely opening double-quotes "handler" => "line", ), ); } }; // Add function to handle single quotes (+ apostrophes) $markdown->inlineTypographySingleQuote = function($excerpt) { if (preg_match("/\w".preg_quote($excerpt["text"], "/")."/", $excerpt["context"], $matches)) { return array( "extent" => 1, "element" => array( "name" => "span", "text" => "’", // apostrophe ), ); } elseif (preg_match_all("/^'([\s\S]*?)'(?=\W?)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[0][0]), "element" => array( "name" => "span", "text" => "‘".$matches[1][0]."’", // single-quotes "handler" => "line", ), ); } elseif (preg_match("/^(')|(\s')/", $excerpt["context"], $matches)) { return array( "extent" => strlen($excerpt["text"]), "element" => array( "name" => "span", "text" => "‘" . substr($excerpt["text"], 1), // Lonely opening single-quote "handler" => "line", ), ); } }; // Don't process inside of inline shortcode tags // This is a fix to stop quoted attributes getting broken when inline // Temporary tags are stripped by $this->stripTemporaryTags() // Once Parsedown 1.8 is used in Grav, the temp tags will be unnecessary $markdown->addInlineType("[", "TypographyShortcode"); $markdown->inlineTypographyShortcode = function($excerpt) { if (preg_match("/\[[\s\S]+?((\".+?\")|(\'.+?\')|(\[.+?\])|([\s\S]+?))*?\]/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[0]), "element" => array( "name" => "temporary-tag", "text" => $matches[0], ), ); } }; $this->enable(["onOutputGenerated" => ["stripTemporaryTags", 0]]); } // Enable ellipsis if ($config["ellipsis"]) { // Add inline type $markdown->addInlineType(".", "TypographyEllipsis"); // Add function to handle inline type $markdown->inlineTypographyEllipsis = function($excerpt) { if (preg_match("/^(\.\.\.)/", $excerpt["text"], $matches)) { return array( "extent" => 3, "element" => array( "name" => "span", "text" => "…", // ellipsis ), ); } }; } // Enable line breaks if ($config["line_breaks"]) { // Add inline type $markdown->addInlineType("\\", "TypographyLineBreaks"); // Add function to handle inline type $markdown->inlineTypographyLineBreaks = function($excerpt) { if (preg_match("/\\\n/", $excerpt["text"], $matches)) { return array( "extent" => 1, "element" => array( "name" => "br", // line break ), ); } }; } // Enable interrobang if ($config["interrobang"]) { // Add inline type $markdown->addInlineType("!", "TypographyInterrobang"); // Add function to handle inline type $markdown->inlineTypographyInterrobang = function($excerpt) { if (preg_match("/^(!\?)/", $excerpt["text"], $matches)) { return array( "extent" => 2, "element" => array( "name" => "span", "text" => "‽", // interrobang ), ); } }; } // Enable plus-minus if ($config["plus_minus"]) { // Add inline type $markdown->addInlineType("+", "TypographyPlusMinus"); // Add function to handle inline type $markdown->inlineTypographyPlusMinus = function($excerpt) { if (preg_match("/^(\+\/?-)/", $excerpt["text"], $matches)) { return array( "extent" => strlen($matches[1]), "element" => array( "name" => "span", "text" => "±", // plus-minus ), ); } }; } // Enable X Times if ($config["x_times"]) { // Add inline type $markdown->addInlineType("x", "TypographyXTimes"); // Add function to handle inline type $markdown->inlineTypographyXTimes = function($excerpt) { if ( (substr($excerpt["text"], 0, 2) == "x ") and (preg_match("/( ".preg_quote($excerpt["text"], "/").")/", $excerpt["context"], $matches)) ) { return array( "extent" => 1, "element" => array( "name" => "span", "text" => "×", // times symbol ), ); } }; } } public function stripTemporaryTags() { // Check that it's an HTML page, abort if not if ($this->grav["page"]->templateFormat() !== 'html') { return; } // Get the rendered content (HTML) $content = $this->grav->output; // Remove the temporary tags $content = str_replace("", "", $content); $content = str_replace("", "", $content); // Remove encoded temporary tags (eg. those generatred by [safe-email]) $content = str_replace("<temporary-tag>", "", $content); $content = str_replace("</temporary-tag>", "", $content); // Rewrite the output $this->grav->output = $content; } }