mikuli.cz

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

commit ce9c353874077594d70ba2a2ba6f862174b35fb9
parent 8757f7a448f3d18f8e9004de34d214471120bcf0
Author: markseu <mark2011@mayberg.se>
Date:   Fri,  9 Nov 2018 09:36:49 +0100

Updated plugins, content handling

Diffstat:
Msystem/plugins/bundle.php | 6+++---
Msystem/plugins/core.php | 77+++++++++++++++++++++++++++++++----------------------------------------------
Msystem/plugins/edit.php | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msystem/plugins/image.php | 8++++----
Msystem/plugins/install-blog.zip | 0
Msystem/plugins/install-wiki.zip | 0
Msystem/plugins/markdown.php | 69++++++++++++++++++++++++++++++++++++---------------------------------
Msystem/plugins/update.php | 28+++++++++++++++++++++++++++-
8 files changed, 224 insertions(+), 135 deletions(-)

diff --git a/system/plugins/bundle.php b/system/plugins/bundle.php @@ -4,7 +4,7 @@ // This file may be used and distributed under the terms of the public license. class YellowBundle { - const VERSION = "0.7.4"; + const VERSION = "0.7.5"; public $yellow; //access to API // Handle initialisation @@ -109,12 +109,12 @@ class YellowBundle { $fileData = $this->yellow->toolbox->readFile($fileName); $fileData = $this->processBundleConvert($scheme, $address, $base, $fileData, $fileName, $type); $fileData = $this->processBundleMinify($scheme, $address, $base, $fileData, $fileName, $type); - if(!empty($fileDataNew)) $fileDataNew .= "\n\n"; + if (!empty($fileDataNew)) $fileDataNew .= "\n\n"; $fileDataNew .= "/* ".basename($fileName)." */\n"; $fileDataNew .= $fileData; } if (defined("DEBUG") && DEBUG>=2) { - if(!empty($fileDataNew)) $fileDataNew .= "\n\n"; + if (!empty($fileDataNew)) $fileDataNew .= "\n\n"; $fileDataNew .= "/* YellowBundle::processBundle file:$fileNameBundle <- ".$this->yellow->page->fileName." */"; } if (!$this->yellow->toolbox->createFile($fileNameBundle, $fileDataNew) || diff --git a/system/plugins/core.php b/system/plugins/core.php @@ -4,7 +4,7 @@ // This file may be used and distributed under the terms of the public license. class YellowCore { - const VERSION = "0.7.8"; + const VERSION = "0.7.9"; public $page; //current page public $pages; //pages from file system public $files; //files from file system @@ -57,15 +57,15 @@ class YellowCore { $this->config->setDefault("contentRootDir", "default/"); $this->config->setDefault("contentHomeDir", "home/"); $this->config->setDefault("contentPagination", "page"); - $this->config->setDefault("contentDefaultFile", "page.txt"); - $this->config->setDefault("contentExtension", ".txt"); + $this->config->setDefault("contentDefaultFile", "page.md"); + $this->config->setDefault("contentExtension", ".md"); $this->config->setDefault("configExtension", ".ini"); $this->config->setDefault("downloadExtension", ".download"); $this->config->setDefault("configFile", "config.ini"); $this->config->setDefault("textFile", "text.ini"); + $this->config->setDefault("errorFile", "page-error-(.*).md"); + $this->config->setDefault("newFile", "page-new-(.*).md"); $this->config->setDefault("languageFile", "language-(.*).txt"); - $this->config->setDefault("errorFile", "page-error-(.*).txt"); - $this->config->setDefault("newFile", "page-new-(.*).txt"); $this->config->setDefault("robotsFile", "robots.txt"); $this->config->setDefault("faviconFile", "favicon.ico"); $this->config->setDefault("serverUrl", ""); @@ -520,17 +520,20 @@ class YellowPage { } } - // Parse page content block - public function parseContentBlock($name, $text, $shortcut) { + // Parse page content shortcut + public function parseContentShortcut($name, $text, $type) { $output = null; foreach ($this->yellow->plugins->plugins as $key=>$value) { - if (method_exists($value["obj"], "onParseContentBlock")) { - $output = $value["obj"]->onParseContentBlock($this, $name, $text, $shortcut); + if (method_exists($value["obj"], "onParseContentShortcut")) { + $output = $value["obj"]->onParseContentShortcut($this, $name, $text, $type); + if (!is_null($output)) break; + } else if (method_exists($value["obj"], "onParseContentBlock")) { //TODO: remove later, old event handler + $output = $value["obj"]->onParseContentBlock($this, $name, $text, true); if (!is_null($output)) break; } } if (is_null($output)) { - if ($name=="yellow" && $shortcut) { + if ($name=="yellow" && $type=="inline") { $output = "Datenstrom Yellow ".YellowCore::VERSION; if ($text=="error") $output = $this->get("pageError"); if ($text=="version") { @@ -545,7 +548,7 @@ class YellowPage { } } } - if (defined("DEBUG") && DEBUG>=3 && !empty($name)) echo "YellowPage::parseContentBlock name:$name shortcut:$shortcut<br/>\n"; + if (defined("DEBUG") && DEBUG>=3 && !empty($name)) echo "YellowPage::parseContentShortcut name:$name type:$type<br/>\n"; return $output; } @@ -708,9 +711,9 @@ class YellowPage { } // Return top-level parent page, null if none - public function getParentTop($homeFailback = true) { + public function getParentTop($homeFallback = false) { $parentTopLocation = $this->yellow->pages->getParentTopLocation($this->location); - if (!$this->yellow->pages->find($parentTopLocation) && $homeFailback) { + if (!$this->yellow->pages->find($parentTopLocation) && $homeFallback) { $parentTopLocation = $this->yellow->pages->getHomeLocation($this->location); } return $this->yellow->pages->find($parentTopLocation); @@ -1481,7 +1484,7 @@ class YellowPlugins { } // Register plugin - public function register($name, $plugin, $obsoleteVersion = 0, $obsoletePriority = 0) { + public function register($name, $plugin, $obsoleteVersion = 0, $obsoletePriority = 0) { //TODO: remove obsolete arguments later if (!$this->isExisting($name) && class_exists($plugin)) { $this->plugins[$name] = array(); $this->plugins[$name]["obj"] = new $plugin; @@ -1557,7 +1560,7 @@ class YellowThemes { } // Register theme - public function register($name, $theme, $obsoleteVersion = 0, $obsoletePriority = 0) { + public function register($name, $theme, $obsoleteVersion = 0, $obsoletePriority = 0) { //TODO: remove obsolete arguments later if (!$this->isExisting($name) && class_exists($theme)) { $this->themes[$name] = array(); $this->themes[$name]["obj"] = new $theme; @@ -2057,37 +2060,6 @@ class YellowLookup { return $includePath ? "$path/$token" : $token; } - // Return new file - public function findFileNew($location, $filePrefix = "") { - $fileName = $this->findFileFromLocation($location); - if (!empty($filePrefix) && !empty($fileName)) { - preg_match("/^([\d\-\_\.]*)(.*)$/", $filePrefix, $matches); - $filePrefix = empty($matches[1]) ? "" : $matches[1]."-"; - $fileText = $this->normaliseName(basename($fileName), true, true); - if (preg_match("/^[\d\-\_\.]*$/", $fileText) && !empty($filePrefix)) $filePrefix = ""; - $fileName = dirname($fileName)."/".$filePrefix.$fileText.$this->yellow->config->get("contentExtension"); - } - if (!is_dir(dirname($fileName))) { - $tokens = explode("/", $fileName); - for ($i=0; $i<count($tokens)-1; ++$i) { - if (!is_dir($path.$tokens[$i])) { - if (!preg_match("/^[\d\-\_\.]+(.*)$/", $tokens[$i])) { - $number = 1; - foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^[\d\-\_\.]+(.*)$/", true, true, false) as $entry) { - if ($number!=1 && $number!=intval($entry)) break; - $number = intval($entry)+1; - } - $tokens[$i] = "$number-".$tokens[$i]; - } - $tokens[$i] = $this->normaliseName($tokens[$i], false, false, true); - } - $path .= $tokens[$i]."/"; - } - $fileName = $path.$tokens[$i]; - } - return $fileName; - } - // Return children from location public function findChildrenFromLocation($location) { $fileNames = array(); @@ -2180,6 +2152,13 @@ class YellowLookup { return preg_replace("/[^\pL\d\-\_]/u", "-", $text); } + // Normalise prefix + public function normalisePrefix($text) { + if (preg_match("/^([\d\-\_\.]*)(.*)$/", $text, $matches)) $prefix = $matches[1]; + if (!empty($prefix) && !preg_match("/[\-\_\.]$/", $prefix)) $prefix .= "-"; + return $prefix; + } + // Normalise array, make keys with same upper/lower case public function normaliseUpperLower($input) { $array = array(); @@ -2574,6 +2553,7 @@ class YellowToolbox { "js" => "application/javascript", "json" => "application/json", "jpg" => "image/jpeg", + "md" => "text/markdown", "png" => "image/png", "svg" => "image/svg+xml", "txt" => "text/plain", @@ -2700,6 +2680,11 @@ class YellowToolbox { return @rename($fileNameSource, $fileNameDestination); } + // Rename directory + public function renameDirectory($pathSource, $pathDestination, $mkdir = false) { + return $pathSource==$pathDestination || $this->renameFile($pathSource, $pathDestination, $mkdir); + } + // Delete file public function deleteFile($fileName, $pathTrash = "") { clearstatcache(); diff --git a/system/plugins/edit.php b/system/plugins/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.7.31"; + const VERSION = "0.7.32"; public $yellow; //access to API public $response; //web response public $users; //user accounts @@ -89,10 +89,10 @@ class YellowEdit { } } - // Handle page content of custom block - public function onParseContentBlock($page, $name, $text, $shortcut) { + // Handle page content of shortcut + public function onParseContentShortcut($page, $name, $text, $type) { $output = null; - if ($name=="edit" && $shortcut) { + if ($name=="edit" && $type=="inline") { $editText = "$name $text"; if (substru($text, 0, 2)=="- ") $editText = trim(substru($text, 2)); $output = "<a href=\"".$page->get("pageEdit")."\">".htmlspecialchars($editText)."</a>"; @@ -643,7 +643,8 @@ class YellowEdit { $this->response->rawDataEdit = $_REQUEST["rawdatasource"]; $this->response->rawDataEndOfLine = $_REQUEST["rawdataendofline"]; $rawData = $_REQUEST["rawdataedit"]; - $page = $this->response->getPageNew($scheme, $address, $base, $location, $fileName, $rawData, $this->response->getEndOfLine()); + $page = $this->response->getPageNew($scheme, $address, $base, $location, $fileName, + $rawData, $this->response->getEndOfLine()); if (!$page->isError()) { if ($this->yellow->toolbox->createFile($page->fileName, $page->rawData, true)) { $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); @@ -671,13 +672,24 @@ class YellowEdit { $page = $this->response->getPageEdit($scheme, $address, $base, $location, $fileName, $this->response->rawDataSource, $this->response->rawDataEdit, $rawDataFile, $this->response->rawDataEndOfLine); if (!$page->isError()) { - if ($this->yellow->toolbox->renameFile($fileName, $page->fileName, true) && + if ($this->yellow->lookup->isFileLocation($location)) { + if ($this->yellow->toolbox->renameFile($fileName, $page->fileName, true) && $this->yellow->toolbox->createFile($page->fileName, $page->rawData)) { - $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); - $statusCode = $this->yellow->sendStatus(303, $location); + $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); + $statusCode = $this->yellow->sendStatus(303, $location); + } else { + $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + } } else { - $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); - $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + if ($this->yellow->toolbox->renameDirectory(dirname($fileName), dirname($page->fileName), true) && + $this->yellow->toolbox->createFile($page->fileName, $page->rawData)) { + $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); + $statusCode = $this->yellow->sendStatus(303, $location); + } else { + $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + } } } else { $this->yellow->page->error(500, $page->get("pageError")); @@ -938,21 +950,21 @@ class YellowResponse { $page->setRequestInformation($scheme, $address, $base, $location, $fileName); $page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0); $this->editContentFile($page, "create"); - if ($this->yellow->lookup->isFileLocation($location) || $this->yellow->pages->find($page->location)) { + if ($this->yellow->pages->find($page->location)) { $page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation")); - $page->fileName = $this->yellow->lookup->findFileNew($page->location, $page->get("published")); + $page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published")); while ($this->yellow->pages->find($page->location) || empty($page->fileName)) { $rawData = $this->yellow->toolbox->setMetaData($page->rawData, "title", $this->getTitleNext($page->rawData)); $page->rawData = $this->normaliseLines($rawData, $endOfLine); $page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation")); - $page->fileName = $this->yellow->lookup->findFileNew($page->location, $page->get("published")); + $page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published")); if (++$pageCounter>999) break; } if ($this->yellow->pages->find($page->location) || empty($page->fileName)) { $page->error(500, "Page '".$page->get("title")."' is not possible!"); } } else { - $page->fileName = $this->yellow->lookup->findFileNew($page->location); + $page->fileName = $this->getPageNewFile($page->location); } if ($this->plugin->getUserRestrictions($this->userEmail, $page->location, $page->fileName)) { $page->error(500, "Page '".$page->get("title")."' is restricted!"); @@ -969,26 +981,20 @@ class YellowResponse { $this->normaliseLines($rawDataEdit, $endOfLine), $this->normaliseLines($rawDataFile, $endOfLine)); $page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0); + $pageSource = new YellowPage($this->yellow); + $pageSource->setRequestInformation($scheme, $address, $base, $location, $fileName); + $pageSource->parseData($this->normaliseLines($rawDataSource, $endOfLine), false, 0); $this->editContentFile($page, "edit"); - if (empty($page->rawData)) $page->error(500, "Page has been modified by someone else!"); - if ($this->yellow->lookup->isFileLocation($location) && !$page->isError()) { - $pageSource = new YellowPage($this->yellow); - $pageSource->setRequestInformation($scheme, $address, $base, $location, $fileName); - $pageSource->parseData($this->normaliseLines($rawDataSource, $endOfLine), false, 0); - if (substrb($pageSource->rawData, 0, $pageSource->metaDataOffsetBytes) != - substrb($page->rawData, 0, $page->metaDataOffsetBytes)) { - $page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation")); - $page->fileName = $this->yellow->lookup->findFileNew($page->location, $page->get("published")); - if ($page->location!=$pageSource->location) { - if (!$this->yellow->lookup->isFileLocation($page->location) || empty($page->fileName)) { - $page->error(500, "Page '".$page->get("title")."' is not possible!"); - } elseif ($this->yellow->pages->find($page->location)) { - $page->error(500, "Page '".$page->get("title")."' already exists!"); - } - } + if ($this->isMetaModified($pageSource, $page) && $page->location!=$this->yellow->pages->getHomeLocation($page->location)) { + $page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation"), true); + $page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published")); + if ($page->location!=$pageSource->location && ($this->yellow->pages->find($page->location) || empty($page->fileName))) { + $page->error(500, "Page '".$page->get("title")."' is not possible!"); } } - if ($this->plugin->getUserRestrictions($this->userEmail, $page->location, $page->fileName)) { + if (empty($page->rawData)) $page->error(500, "Page has been modified by someone else!"); + if ($this->plugin->getUserRestrictions($this->userEmail, $page->location, $page->fileName) || + $this->plugin->getUserRestrictions($this->userEmail, $pageSource->location, $pageSource->fileName)) { $page->error(500, "Page '".$page->get("title")."' is restricted!"); } return $page; @@ -1175,7 +1181,7 @@ class YellowResponse { } // Return location for new/modified page - public function getPageNewLocation($rawData, $pageLocation, $pageNewLocation) { + public function getPageNewLocation($rawData, $pageLocation, $pageNewLocation, $pageMatchLocation = false) { $location = empty($pageNewLocation) ? "@title" : $pageNewLocation; $location = preg_replace("/@title/i", $this->getPageNewTitle($rawData), $location); $location = preg_replace("/@timestamp/i", $this->getPageNewData($rawData, "published", true, "U"), $location); @@ -1186,7 +1192,14 @@ class YellowResponse { $location = preg_replace("/@tag/i", $this->getPageNewData($rawData, "tag", true), $location); $location = preg_replace("/@author/i", $this->getPageNewData($rawData, "author", true), $location); if (!preg_match("/^\//", $location)) { - $location = $this->yellow->lookup->getDirectoryLocation($pageLocation).$location; + if ($this->yellow->lookup->isFileLocation($pageLocation) || !$pageMatchLocation) { + $location = $this->yellow->lookup->getDirectoryLocation($pageLocation).$location; + } else { + $location = $this->yellow->lookup->getDirectoryLocation(rtrim($pageLocation, "/")).$location; + } + } + if ($pageMatchLocation) { + $location = rtrim($location, "/").($this->yellow->lookup->isFileLocation($pageLocation) ? "" : "/"); } return $location; } @@ -1209,7 +1222,63 @@ class YellowResponse { $value = $this->yellow->lookup->normaliseName($value, true, false, true); return trim(preg_replace("/-+/", "-", $value), "-"); } - + + // Return file name for new/modified page + public function getPageNewFile($location, $pageFileName = "", $pagePrefix = "") { + $fileName = $this->yellow->lookup->findFileFromLocation($location); + if (!empty($fileName)) { + if (!is_dir(dirname($fileName))) { + $path = ""; + $tokens = explode("/", $fileName); + for ($i=0; $i<count($tokens)-1; ++$i) { + if (!is_dir($path.$tokens[$i])) { + if (!preg_match("/^[\d\-\_\.]+(.*)$/", $tokens[$i])) { + $number = 1; + foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^[\d\-\_\.]+(.*)$/", true, true, false) as $entry) { + if ($number!=1 && $number!=intval($entry)) break; + $number = intval($entry)+1; + } + $tokens[$i] = "$number-".$tokens[$i]; + } + $tokens[$i] = $this->yellow->lookup->normaliseName($tokens[$i], false, false, true); + } + $path .= $tokens[$i]."/"; + } + $fileName = $path.$tokens[$i]; + $pageFileName = empty($pageFileName) ? $fileName : $pageFileName; + } + $prefix = $this->getPageNewPrefix($location, $pageFileName, $pagePrefix); + if ($this->yellow->lookup->isFileLocation($location)) { + preg_match("#^(.*)\/(.+?)$#", $fileName, $matches); + $path = $matches[1]; + $text = $this->yellow->lookup->normaliseName($matches[2], true, true); + if (preg_match("/^[\d\-\_\.]*$/", $text)) $prefix = ""; + $fileName = $path."/".$prefix.$text.$this->yellow->config->get("contentExtension"); + } else { + preg_match("#^(.*)\/(.+?)$#", dirname($fileName), $matches); + $path = $matches[1]; + $text = $this->yellow->lookup->normaliseName($matches[2], true, false); + if (preg_match("/^[\d\-\_\.]*$/", $text)) $prefix = ""; + $fileName = $path."/".$prefix.$text."/".$this->yellow->config->get("contentDefaultFile"); + } + } + return $fileName; + } + + // Return prefix for new/modified page + public function getPageNewPrefix($location, $pageFileName, $pagePrefix) { + if (empty($pagePrefix)) { + if ($this->yellow->lookup->isFileLocation($location)) { + preg_match("#^(.*)\/(.+?)$#", $pageFileName, $matches); + $pagePrefix = $matches[2]; + } else { + preg_match("#^(.*)\/(.+?)$#", dirname($pageFileName), $matches); + $pagePrefix = $matches[2]; + } + } + return $this->yellow->lookup->normalisePrefix($pagePrefix, true); + } + // Return location for new file public function getFileNewLocation($fileNameShort, $pageLocation, $fileNewLocation) { $location = empty($fileNewLocation) ? $this->yellow->config->get("editUploadNewLocation") : $fileNewLocation; @@ -1240,14 +1309,6 @@ class YellowResponse { return strtoloweru(trim($parentTopLocation, "/")); } - // Return next title - public function getTitleNext($rawData) { - preg_match("/^(.*?)(\d*)$/", $this->yellow->toolbox->getMetaData($rawData, "title"), $matches); - $titleText = $matches[1]; - $titleNumber = strempty($matches[2]) ? " 2" : $matches[2]+1; - return $titleText.$titleNumber; - } - // Return next file name public function getFileNext($fileNameShort) { preg_match("/^(.*?)(\d*)(\..*?)?$/", $fileNameShort, $matches); @@ -1256,7 +1317,15 @@ class YellowResponse { $fileExtension = $matches[3]; return $fileText.$fileNumber.$fileExtension; } - + + // Return next title + public function getTitleNext($rawData) { + preg_match("/^(.*?)(\d*)$/", $this->yellow->toolbox->getMetaData($rawData, "title"), $matches); + $titleText = $matches[1]; + $titleNumber = strempty($matches[2]) ? " 2" : $matches[2]+1; + return $titleText.$titleNumber; + } + // Normalise text lines, convert line endings public function normaliseLines($text, $endOfLine = "lf") { if ($endOfLine=="lf") { @@ -1337,6 +1406,12 @@ class YellowResponse { } } + // Check if meta data has been modified + public function isMetaModified($pageSource, $pageOther) { + return substrb($pageSource->rawData, 0, $pageSource->metaDataOffsetBytes) != + substrb($pageOther->rawData, 0, $pageOther->metaDataOffsetBytes); + } + // Check if active public function isActive() { return $this->active; @@ -1347,16 +1422,16 @@ class YellowResponse { return !empty($this->userEmail); } - // Check if user has restrictions - public function isUserRestrictions() { - return empty($this->userEmail) || $this->userRestrictions; - } - // Check if user is webmaster public function isUserWebmaster() { return !empty($this->userEmail) && $this->userEmail==$this->yellow->config->get("email"); } + // Check if user has restrictions + public function isUserRestrictions() { + return empty($this->userEmail) || $this->userRestrictions; + } + // Check if login has restrictions public function isLoginRestrictions() { return $this->yellow->config->get("editLoginRestrictions"); diff --git a/system/plugins/image.php b/system/plugins/image.php @@ -4,7 +4,7 @@ // This file may be used and distributed under the terms of the public license. class YellowImage { - const VERSION = "0.7.7"; + const VERSION = "0.7.8"; public $yellow; //access to API public $graphicsLibrary; //graphics library support? (boolean) @@ -21,10 +21,10 @@ class YellowImage { $this->graphicsLibrary = $this->isGraphicsLibrary(); } - // Handle page content of custom block - public function onParseContentBlock($page, $name, $text, $shortcut) { + // Handle page content of shortcut + public function onParseContentShortcut($page, $name, $text, $type) { $output = null; - if ($name=="image" && $shortcut) { + if ($name=="image" && $type=="inline") { if (!$this->graphicsLibrary) { $this->yellow->page->error(500, "Plugin 'image' requires GD library with gif/jpg/png support!"); return $output; diff --git a/system/plugins/install-blog.zip b/system/plugins/install-blog.zip Binary files differ. diff --git a/system/plugins/install-wiki.zip b/system/plugins/install-wiki.zip Binary files differ. diff --git a/system/plugins/markdown.php b/system/plugins/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.7.2"; + const VERSION = "0.7.3"; public $yellow; //access to API // Handle initialisation @@ -3752,56 +3752,48 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser { parent::__construct(); } - // Return unique id attribute - public function getIdAttribute($text) { - $text = $this->yellow->lookup->normaliseName($text, true, false, true); - $text = trim(preg_replace("/-+/", "-", $text), "-"); - if (is_null($this->idAttributes[$text])) { - $this->idAttributes[$text] = $text; - $attr = " id=\"$text\""; - } - return $attr; - } - // Handle links public function doAutoLinks($text) { $text = preg_replace_callback("/<(\w+:[^\'\">\s]+)>/", array(&$this, "_doAutoLinks_url_callback"), $text); $text = preg_replace_callback("/<([\w\+\-\.]+@[\w\-\.]+)>/", array(&$this, "_doAutoLinks_email_callback"), $text); - $text = preg_replace_callback("/\[\-\-(.*?)\-\-\]/", array(&$this, "_doAutoLinks_comment_callback"), $text); - $text = preg_replace_callback("/\[(\w+)(.*?)\]/", array(&$this, "_doAutoLinks_shortcut_callback"), $text); - $text = preg_replace_callback("/\:([\w\+\-\_]+)\:/", array(&$this, "_doAutoLinks_shortcode_callback"), $text); + $text = preg_replace_callback("/^\s*\[(\w+)(.*?)\]\s*$/", array(&$this, "_doAutoLinks_shortcutBlock_callback"), $text); + $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("/([\w\+\-\.]+@[\w\-\.]+\.[\w]{2,4})/", array(&$this, "_doAutoLinks_email_callback"), $text); return $text; } - // Handle comments - public function _doAutoLinks_comment_callback($matches) { - $text = $matches[1]; - $output = "<!--".htmlspecialchars($text, ENT_NOQUOTES)."-->"; - if ($text[0]=="-") $output = ""; - return $this->hashBlock($output); + // Handle shortcuts, block style + public function _doAutoLinks_shortcutBlock_callback($matches) { + $output = $this->page->parseContentShortcut($matches[1], trim($matches[2]), "block"); + return is_null($output) ? $matches[0] : $this->hashBlock($output); } - // Handle shortcuts - public function _doAutoLinks_shortcut_callback($matches) { - $output = $this->page->parseContentBlock($matches[1], trim($matches[2]), true); - if (is_null($output)) $output = htmlspecialchars($matches[0], ENT_NOQUOTES); - return substr($output, 0, 4)=="<div" ? $this->hashBlock(trim($output)) : $this->hashPart(trim($output)); + // Handle shortcuts, inline style + public function _doAutoLinks_shortcutInline_callback($matches) { + $output = $this->page->parseContentShortcut($matches[1], trim($matches[2]), "inline"); + return is_null($output) ? $matches[0] : $this->hashPart($output); } - - // Handle shortcodes - public function _doAutoLinks_shortcode_callback($matches) { - $output = $this->page->parseContentBlock("", $matches[1], true); - if (is_null($output)) $output = htmlspecialchars($matches[0], ENT_NOQUOTES); - return $this->hashPart($output); + + // Handle shortcuts, comment style + public function _doAutoLinks_shortcutComment_callback($matches) { + $output = "<!--".htmlspecialchars($matches[1], ENT_NOQUOTES)."-->"; + return $this->hashBlock($output); + } + + // Handle shortcuts, symbol style + public function _doAutoLinks_shortcutSymbol_callback($matches) { + $output = $this->page->parseContentShortcut("", $matches[1], "symbol"); + return is_null($output) ? $matches[0] : $this->hashPart($output); } // Handle fenced code blocks public function _doFencedCodeBlocks_callback($matches) { $text = $matches[4]; $name = empty($matches[2]) ? "" : "$matches[2] $matches[3]"; - $output = $this->page->parseContentBlock($name, $text, false); + $output = $this->page->parseContentShortcut($name, $text, "code"); if (is_null($output)) { $attr = $this->doExtraAttributes("pre", ".$matches[2] $matches[3]"); $output = "<pre$attr><code>".htmlspecialchars($text, ENT_NOQUOTES)."</code></pre>"; @@ -3862,4 +3854,15 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser { $output .= $this->empty_element_suffix; return $this->hashPart($output); } + + // Return unique id attribute + public function getIdAttribute($text) { + $text = $this->yellow->lookup->normaliseName($text, true, false, true); + $text = trim(preg_replace("/-+/", "-", $text), "-"); + if (is_null($this->idAttributes[$text])) { + $this->idAttributes[$text] = $text; + $attr = " id=\"$text\""; + } + return $attr; + } } diff --git a/system/plugins/update.php b/system/plugins/update.php @@ -4,7 +4,7 @@ // This file may be used and distributed under the terms of the public license. class YellowUpdate { - const VERSION = "0.7.22"; + const VERSION = "0.7.23"; const PRIORITY = "2"; public $yellow; //access to API public $updates; //number of updates @@ -30,6 +30,32 @@ class YellowUpdate { $this->yellow->config->save($fileNameConfig, array("staticDir" => "public/")); } } + if ($update) { //TODO: remove later, converts old Markdown extension + $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); + $fileNameError = $this->yellow->config->get("configDir")."system-error.log"; + if ($this->yellow->config->get("contentDefaultFile")=="page.txt") { + $config = array("contentDefaultFile" => "page.md", "contentExtension" => ".md", + "errorFile" => "page-error-(.*).md", "newFile" => "page-new-(.*).md"); + $this->yellow->config->save($fileNameConfig, $config); + $path = $this->yellow->config->get("contentDir"); + foreach ($this->yellow->toolbox->getDirectoryEntriesRecursive($path, "/^.*\.txt$/", true, false) as $entry) { + if (!$this->yellow->toolbox->renameFile($entry, str_replace(".txt", ".md", $entry))) { + $fileDataError .= "ERROR renaming file '$entry'!\n"; + } + } + $path = $this->yellow->config->get("configDir"); + foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.txt$/", true, false) as $entry) { + if (basename($entry) == $this->yellow->config->get("robotsFile")) continue; + if (!$this->yellow->toolbox->renameFile($entry, str_replace(".txt", ".md", $entry))) { + $fileDataError .= "ERROR renaming file '$entry!'\n"; + } + } + if (!empty($fileDataError)) { + $this->yellow->toolbox->createFile($fileNameError, $fileDataError); + } + $_GET["clean-url"] = "system-updated"; + } + } if ($update) { $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); $fileData = $this->yellow->toolbox->readFile($fileNameConfig);