mikuli.cz

:)
git clone https://git.sr.ht/~ashymad/mikuli.cz
Log | Files | Refs

commit 6e96dad4a232fe0050ce6c9c23683d5757e70b60
parent 7a1f68e9f927e2fb9150b3376924c085082cba98
Author: markseu <mark2011@mayberg.se>
Date:   Thu, 21 Mar 2019 11:58:12 +0100

Added support for Markdown strikethrough and task list

Diffstat:
Msystem/extensions/edit.js | 1+
Msystem/extensions/edit.php | 62+++++++++++++++++++++++++++++++-------------------------------
Msystem/extensions/markdown.php | 51++++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 78 insertions(+), 36 deletions(-)

diff --git a/system/extensions/edit.js b/system/extensions/edit.js @@ -638,6 +638,7 @@ yellow.edit = { "<ul class=\"yellow-dropdown yellow-dropdown-menu\">"+ "<li><a href=\"#\" id=\"yellow-popup-list-ul\" data-action=\"toolbar\" data-status=\"ul\">"+this.getText("ToolbarUl")+"</a></li>"+ "<li><a href=\"#\" id=\"yellow-popup-list-ol\" data-action=\"toolbar\" data-status=\"ol\">"+this.getText("ToolbarOl")+"</a></li>"+ + "<li><a href=\"#\" id=\"yellow-popup-list-tl\" data-action=\"toolbar\" data-status=\"tl\">"+this.getText("ToolbarTl")+"</a></li>"+ "</ul>"; break; case "yellow-popup-emojiawesome": diff --git a/system/extensions/edit.php b/system/extensions/edit.php @@ -4,7 +4,7 @@ // This file may be used and distributed under the terms of the public license. class YellowEdit { - const VERSION = "0.8.3"; + const VERSION = "0.8.4"; const TYPE = "feature"; public $yellow; //access to API public $response; //web response @@ -14,9 +14,9 @@ class YellowEdit { // Handle initialisation public function onLoad($yellow) { $this->yellow = $yellow; - $this->response = new YellowResponse($yellow); - $this->users = new YellowUsers($yellow); - $this->merge = new YellowMerge($yellow); + $this->response = new YellowEditResponse($yellow); + $this->users = new YellowEditUsers($yellow); + $this->merge = new YellowEditMerge($yellow); $this->yellow->system->setDefault("editLocation", "/edit/"); $this->yellow->system->setDefault("editUploadNewLocation", "/media/@group/@filename"); $this->yellow->system->setDefault("editUploadExtensions", ".gif, .jpg, .pdf, .png, .svg, .tgz, .zip"); @@ -923,7 +923,7 @@ class YellowEdit { } } -class YellowResponse { +class YellowEditResponse { public $yellow; //access to API public $extension; //access to extension public $active; //location is active? (boolean) @@ -1132,7 +1132,7 @@ class YellowResponse { $toolbarButtons = $this->yellow->system->get("editToolbarButtons"); if ($toolbarButtons=="auto") { $toolbarButtons = ""; - if ($this->yellow->extensions->isExisting("markdown")) $toolbarButtons = "preview, format, bold, italic, code, list, link, file"; + if ($this->yellow->extensions->isExisting("markdown")) $toolbarButtons = "preview, format, bold, italic, strikethrough, code, list, link, file"; if ($this->yellow->extensions->isExisting("emojiawesome")) $toolbarButtons .= ", emojiawesome"; if ($this->yellow->extensions->isExisting("fontawesome")) $toolbarButtons .= ", fontawesome"; if ($this->yellow->extensions->isExisting("draft")) $toolbarButtons .= ", draft"; @@ -1447,7 +1447,7 @@ class YellowResponse { } } -class YellowUsers { +class YellowEditUsers { public $yellow; //access to API public $users; //registered users @@ -1458,7 +1458,7 @@ class YellowUsers { // Load users from file public function load($fileName) { - if (defined("DEBUG") && DEBUG>=2) echo "YellowUsers::load file:$fileName<br/>\n"; + if (defined("DEBUG") && DEBUG>=2) echo "YellowEditUsers::load file:$fileName<br/>\n"; $fileData = $this->yellow->toolbox->readFile($fileName); foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { if (preg_match("/^\#/", $line)) continue; @@ -1466,7 +1466,7 @@ class YellowUsers { if (!empty($matches[1]) && !empty($matches[2])) { list($hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home) = explode(",", $matches[2]); $this->set($matches[1], $hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home); - if (defined("DEBUG") && DEBUG>=3) echo "YellowUsers::load email:$matches[1]<br/>\n"; + if (defined("DEBUG") && DEBUG>=3) echo "YellowEditUsers::load email:$matches[1]<br/>\n"; } } } @@ -1694,7 +1694,7 @@ class YellowUsers { } } -class YellowMerge { +class YellowEditMerge { public $yellow; //access to API const ADD = "+"; //merge types const MODIFY = "*"; @@ -1735,36 +1735,36 @@ class YellowMerge { --$otherEnd; } for ($pos=0; $pos<$textStart; ++$pos) { - array_push($diff, array(YellowMerge::SAME, $textSource[$pos], false)); + array_push($diff, array(YellowEditMerge::SAME, $textSource[$pos], false)); } $lcs = $this->buildDiffLCS($textSource, $textOther, $textStart, $sourceEnd-$textStart, $otherEnd-$textStart); for ($x=0,$y=0,$xEnd=$otherEnd-$textStart,$yEnd=$sourceEnd-$textStart; $x<$xEnd || $y<$yEnd;) { $max = $lcs[$y][$x]; if ($y<$yEnd && $lcs[$y+1][$x]==$max) { - array_push($diff, array(YellowMerge::REMOVE, $textSource[$textStart+$y], false)); + array_push($diff, array(YellowEditMerge::REMOVE, $textSource[$textStart+$y], false)); if ($lastRemove==-1) $lastRemove = count($diff)-1; ++$y; continue; } if ($x<$xEnd && $lcs[$y][$x+1]==$max) { - if ($lastRemove==-1 || $diff[$lastRemove][0]!=YellowMerge::REMOVE) { - array_push($diff, array(YellowMerge::ADD, $textOther[$textStart+$x], false)); + if ($lastRemove==-1 || $diff[$lastRemove][0]!=YellowEditMerge::REMOVE) { + array_push($diff, array(YellowEditMerge::ADD, $textOther[$textStart+$x], false)); $lastRemove = -1; } else { - $diff[$lastRemove] = array(YellowMerge::MODIFY, $textOther[$textStart+$x], false); + $diff[$lastRemove] = array(YellowEditMerge::MODIFY, $textOther[$textStart+$x], false); ++$lastRemove; if (count($diff)==$lastRemove) $lastRemove = -1; } ++$x; continue; } - array_push($diff, array(YellowMerge::SAME, $textSource[$textStart+$y], false)); + array_push($diff, array(YellowEditMerge::SAME, $textSource[$textStart+$y], false)); $lastRemove = -1; ++$x; ++$y; } for ($pos=$sourceEnd;$pos<$sourceSize; ++$pos) { - array_push($diff, array(YellowMerge::SAME, $textSource[$pos], false)); + array_push($diff, array(YellowEditMerge::SAME, $textSource[$pos], false)); } return $diff; } @@ -1791,27 +1791,27 @@ class YellowMerge { while ($posMine<count($diffMine) && $posYours<count($diffYours)) { $typeMine = $diffMine[$posMine][0]; $typeYours = $diffYours[$posYours][0]; - if ($typeMine==YellowMerge::SAME) { + if ($typeMine==YellowEditMerge::SAME) { array_push($diff, $diffYours[$posYours]); - } elseif ($typeYours==YellowMerge::SAME) { + } elseif ($typeYours==YellowEditMerge::SAME) { array_push($diff, $diffMine[$posMine]); - } elseif ($typeMine==YellowMerge::ADD && $typeYours==YellowMerge::ADD) { + } elseif ($typeMine==YellowEditMerge::ADD && $typeYours==YellowEditMerge::ADD) { $this->mergeConflict($diff, $diffMine[$posMine], $diffYours[$posYours], false); - } elseif ($typeMine==YellowMerge::MODIFY && $typeYours==YellowMerge::MODIFY) { + } elseif ($typeMine==YellowEditMerge::MODIFY && $typeYours==YellowEditMerge::MODIFY) { $this->mergeConflict($diff, $diffMine[$posMine], $diffYours[$posYours], false); - } elseif ($typeMine==YellowMerge::REMOVE && $typeYours==YellowMerge::REMOVE) { + } elseif ($typeMine==YellowEditMerge::REMOVE && $typeYours==YellowEditMerge::REMOVE) { array_push($diff, $diffMine[$posMine]); - } elseif ($typeMine==YellowMerge::ADD) { + } elseif ($typeMine==YellowEditMerge::ADD) { array_push($diff, $diffMine[$posMine]); - } elseif ($typeYours==YellowMerge::ADD) { + } elseif ($typeYours==YellowEditMerge::ADD) { array_push($diff, $diffYours[$posYours]); } else { $this->mergeConflict($diff, $diffMine[$posMine], $diffYours[$posYours], true); } - if (defined("DEBUG") && DEBUG>=2) echo "YellowMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n"; - if ($typeMine==YellowMerge::ADD || $typeYours==YellowMerge::ADD) { - if ($typeMine==YellowMerge::ADD) ++$posMine; - if ($typeYours==YellowMerge::ADD) ++$posYours; + if (defined("DEBUG") && DEBUG>=2) echo "YellowEditMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n"; + if ($typeMine==YellowEditMerge::ADD || $typeYours==YellowEditMerge::ADD) { + if ($typeMine==YellowEditMerge::ADD) ++$posMine; + if ($typeYours==YellowEditMerge::ADD) ++$posYours; } else { ++$posMine; ++$posYours; @@ -1821,13 +1821,13 @@ class YellowMerge { array_push($diff, $diffMine[$posMine]); $typeMine = $diffMine[$posMine][0]; $typeYours = " "; - if (defined("DEBUG") && DEBUG>=2) echo "YellowMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n"; + if (defined("DEBUG") && DEBUG>=2) echo "YellowEditMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n"; } for (;$posYours<count($diffYours); ++$posYours) { array_push($diff, $diffYours[$posYours]); $typeYours = $diffYours[$posYours][0]; $typeMine = " "; - if (defined("DEBUG") && DEBUG>=2) echo "YellowMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n"; + if (defined("DEBUG") && DEBUG>=2) echo "YellowEditMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n"; } return $diff; } @@ -1847,7 +1847,7 @@ class YellowMerge { $output = ""; if (!$showDiff) { for ($i=0; $i<count($diff); ++$i) { - if ($diff[$i][0]!=YellowMerge::REMOVE) $output .= $diff[$i][1]; + if ($diff[$i][0]!=YellowEditMerge::REMOVE) $output .= $diff[$i][1]; $conflict |= $diff[$i][2]; } } else { diff --git a/system/extensions/markdown.php b/system/extensions/markdown.php @@ -4,7 +4,7 @@ // This file may be used and distributed under the terms of the public license. class YellowMarkdown { - const VERSION = "0.8.2"; + const VERSION = "0.8.4"; const TYPE = "feature"; public $yellow; //access to API @@ -3750,9 +3750,30 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser { return $yellow->lookup->normaliseLocation($url, $page->location, $page->safeMode && $page->statusCode==200); }; + $this->span_gamut += array("doStrikethrough" => 55); + $this->escape_chars .= "~"; parent::__construct(); } + // Handle striketrough + public function doStrikethrough($text) { + $parts = preg_split("/(?<![~])(~~)(?![~])/", $text, null, PREG_SPLIT_DELIM_CAPTURE); + if (count($parts)>3) { + $text = ""; + $open = false; + foreach ($parts as $part) { + if ($part=="~~") { + $text .= $open ? "</del>" : "<del>"; + $open = !$open; + } else { + $text .= $part; + } + } + if ($open) $text .= "</del>"; + } + return $text; + } + // Handle links public function doAutoLinks($text) { $text = preg_replace_callback("/<(\w+:[^\'\">\s]+)>/", array(&$this, "_doAutoLinks_url_callback"), $text); @@ -3761,7 +3782,7 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser { $text = preg_replace_callback("/\[(\w+)(.*?)\]/", array(&$this, "_doAutoLinks_shortcutInline_callback"), $text); $text = preg_replace_callback("/\[\-\-(.*?)\-\-\]/", array(&$this, "_doAutoLinks_shortcutComment_callback"), $text); $text = preg_replace_callback("/\:([\w\+\-\_]+)\:/", array(&$this, "_doAutoLinks_shortcutSymbol_callback"), $text); - $text = preg_replace_callback("/((http|https|ftp):\/\/\S+[^\'\"\,\.\;\:\s]+)/", array(&$this, "_doAutoLinks_url_callback"), $text); + $text = preg_replace_callback("/((http|https|ftp):\/\/\S+[^\'\"\,\.\;\:\*\~\s]+)/", array(&$this, "_doAutoLinks_url_callback"), $text); $text = preg_replace_callback("/([\w\+\-\.]+@[\w\-\.]+\.[\w]{2,4})/", array(&$this, "_doAutoLinks_email_callback"), $text); return $text; } @@ -3838,17 +3859,14 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser { // Handle inline images public function _doImages_inline_callback($matches) { - $width = $height = 0; $src = $matches[3]=="" ? $matches[4] : $matches[3]; if (!preg_match("/^\w+:/", $src)) { - list($width, $height) = $this->yellow->toolbox->detectImageInformation($this->yellow->system->get("imageDir").$src); $src = $this->yellow->system->get("serverBase").$this->yellow->system->get("imageLocation").$src; } $alt = $matches[2]; $title = $matches[7]=="" ? $matches[2] : $matches[7]; $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); $output = "<img src=\"".$this->encodeURLAttribute($src)."\""; - if ($width && $height) $output .= " width=\"$width\" height=\"$height\""; if (!empty($alt)) $output .= " alt=\"".$this->encodeAttribute($alt)."\""; if (!empty($title)) $output .= " title=\"".$this->encodeAttribute($title)."\""; $output .= $attr; @@ -3856,6 +3874,29 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser { return $this->hashPart($output); } + // Handle lists, task list + public function _processListItems_callback($matches) { + $attr = ""; + $item = $matches[4]; + $leadingLine = $matches[1]; + $tailingLine = $matches[5]; + if ($leadingLine || $tailingLine || preg_match('/\n{2,}/', $item)) + { + $item = $matches[2].str_repeat(' ', strlen($matches[3])).$item; + $item = $this->runBlockGamut($this->outdent($item)."\n"); + } else { + $item = $this->doLists($this->outdent($item)); + $item = $this->formParagraphs($item, false); + $token = substr($item, 0, 4); + if ($token=="[ ] " || $token=="[x] ") { + $attr = " class=\"task-list-item\""; + $item = ($token=='[ ] ' ? "<input type=\"checkbox\" disabled=\"disabled\" /> " : + "<input type=\"checkbox\" disabled=\"disabled\" checked=\"checked\" /> ").substr($item, 4); + } + } + return "<li$attr>".$item."</li>\n"; + } + // Return unique id attribute public function getIdAttribute($text) { $text = $this->yellow->lookup->normaliseName($text, true, false, true);