Updated plugins, content handling

This commit is contained in:
markseu 2018-11-09 09:36:49 +01:00
parent 8757f7a448
commit ce9c353874
8 changed files with 224 additions and 135 deletions

View file

@ -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) ||

View file

@ -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();

View file

@ -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");

View file

@ -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;

Binary file not shown.

Binary file not shown.

View file

@ -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 = "";
// 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, 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 shortcuts, comment style
public function _doAutoLinks_shortcutComment_callback($matches) {
$output = "<!--".htmlspecialchars($matches[1], ENT_NOQUOTES)."-->";
return $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 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, 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;
}
}

View file

@ -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);