register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'ckgdoku_save_preprocess'); } function ckgdoku_save_preprocess(Doku_Event $event){ global $ACT; if (!isset($_REQUEST['ckgdoku']) || ! is_array($ACT) || !(isset($ACT['save']) || isset($ACT['preview']))) return; if (isset($_REQUEST["fontdel"]) ) { msg($this->getLang("fontdel"),1); } if (isset($_REQUEST["formatdel"]) ) { msg($this->getLang("formatdel"),1); } global $TEXT, $conf; if (!$TEXT) return; $preserve_enc = $this->getConf('preserve_enc'); $deaccent = $conf['deaccent'] == 0 ? false : true; $TEXT = $_REQUEST['fck_wikitext']; if(!preg_match('/^\s+(\-|\*)/',$TEXT)) { $TEXT = trim($TEXT); } $TEXT = preg_replace_callback( '|\{\{data:(.*?);base64|ms', create_function( '$matches', 'if(!preg_match("/image/",$matches[1])) { return "{{data:image/jpeg;base64"; } return $matches[0];' ),$TEXT); if(strpos($TEXT,'data:image') !== false) { $TEXT = preg_replace_callback( '|\{\{(\s*)data:image\/(\w+;base64,\s*)(.*?)\?nolink&(\s*)\}\}|ms', create_function( '$matches', 'list($ext,$base) = explode(";",$matches[2]); if($ext == "jpeg" || $ext == "tiff") $ext = "jpg"; if(function_exists("imagecreatefromstring") && !imagecreatefromstring (base64_decode($matches[3]))) { msg("Clipboard paste: invalid $ext image format"); return "{{" . BROKEN_IMAGE . "}}"; } global $INFO,$conf; $ns = getNS($INFO["id"]); $ns = trim($ns); if(!empty($ns)) { $ns = ":$ns:"; $dir = str_replace(":","/",$ns); } else { // root namespace $dir = "/"; $ns = ":"; } $fn = md5($matches[3]) . ".$ext"; $path = $conf["mediadir"] . $dir . $fn; @io_makeFileDir($path); if(!file_exists($path)) { @file_put_contents($path, base64_decode($matches[3])); } else { msg("file for this image previousely saved",2); } $left = "{{"; $right = "}}"; if($matches[1]) $left .= $matches[1]; if($matches[4]) $right = $matches[4] . $right; $retv = "$left" . $ns. $fn . "$right"; return $retv;' ), $TEXT ); } $TEXT = str_replace('%%', "FCKGPERCENTESC", $TEXT); if($deaccent || $preserve_enc) { $TEXT = preg_replace_callback('/^(.*?)(\[\[.*?\]\])*(.*?)$/ms', create_function( '$matches', '$matches[1] = preg_replace("/%([A-F0-9]{1,3})/i", "URLENC_PERCENT$1", $matches[1]); $matches[2] = preg_replace("/%([A-F0-9]{1,3})/i", "URLENC_PERCENT$1", $matches[2]); $matches[3] = preg_replace("/%([A-F0-9]{1,3})/i", "URLENC_PERCENT$1", $matches[3]); return $matches[1].$matches[2].$matches[3];' ), $TEXT ); } $TEXT = rawurldecode($TEXT); $TEXT = preg_replace('/NOWIKI_%_NOWIKI_%_/', '%%',$TEXT); $TEXT = preg_replace('/URLENC_PERCENT/', '%',$TEXT); $TEXT = preg_replace('/NOWIKI_(.)_/', '$1',$TEXT); /* preserve newlines in code blocks */ $TEXT = preg_replace_callback( '/(|)(.*?)(<\/code>|<\/file>)/ms', create_function( '$matches', 'return str_replace("\n", "__code_NL__",$matches[0]);' ), $TEXT ); $TEXT = preg_replace('/^\s*[\r\n]$/ms',"__n__", $TEXT); $TEXT = preg_replace('/oIWIKIo|cIWIKIc/ms',"", $TEXT); $TEXT = preg_replace('/\r/ms',"", $TEXT); $TEXT = preg_replace('/^\s+(?=\^|\|)/ms',"", $TEXT); $TEXT = preg_replace('/__n__/',"\n", $TEXT); $TEXT = str_replace("__code_NL__","\n", $TEXT); $TEXT = str_replace("FCKGPERCENTESC", '%%', $TEXT); if($this->getConf('complex_tables')) { $TEXT = str_replace('~~COMPLEX_TABLES~~','',$TEXT); } $TEXT .= "\n"; // Removes relics of markup characters left over after acronym markup has been removed //$TEXT = preg_replace('/([\*\/_]{2})\s+\\1\s*([A-Z]+)\s*\\1+/ms',"$2",$TEXT); $pos = strpos($TEXT, 'MULTI_PLUGIN_OPEN'); if($pos !== false) { $TEXT = preg_replace_callback( '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms', create_function( '$matches', 'return preg_replace("/\\\\\\\\/ms","\n",$matches[0]);' ), $TEXT ); $TEXT = preg_replace_callback( '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms', create_function( '$matches', 'return preg_replace("/^\s+/ms","",$matches[0]);' ), $TEXT ); $TEXT = str_replace("~~MULTI_PLUGIN_OPEN~~","~~MULTI_PLUGIN_OPEN~~\n",$TEXT); } if(strpos($TEXT,'L_PARgr') !== false) { $TEXT = preg_replace_callback( '|\(\((.*?)\)\)|ms', create_function( '$matches', 'return "((" . trim($matches[1]) . "))"; ' ), $TEXT ); $TEXT = str_replace('L_PARgr', '(',$TEXT); $TEXT = str_replace('R_PARgr', ')',$TEXT); } $this->replace_entities(); /*Remove urls from linkonly images inserted after second and additional saves, resulting in multiple urls corrupting HTML output */ $TEXT = preg_replace("/\{\{http:\/\/.*?fetch.php\?media=(.*?linkonly.*?)\}\}/",'{{' . "$1" .'}}',$TEXT); $TEXT = str_replace('< nowiki >', '%%%%',$TEXT); $TEXT = preg_replace_callback( '#\[\[(.*?)\]\]#ms', function($matches){ global $ID, $conf; $qs = ""; if(preg_match("/\[\[http/",$matches[0])) return $matches[0]; //not an internal link if(preg_match("#\[\[.*?\|\{\{.*?\}\}\]\]#", $matches[0],$matches_1)) { if(!$this->getConf('rel_links')) { return $matches[0]; } $link = explode('?',$matches[1]); list($link_id,$linktext) = explode('|', $link[0]); $current_id = $this->abs2rel($link_id,$ID); return preg_replace("#$link_id#",$current_id, $matches[0]); } $link = explode('?',$matches[1]); list($link_id,$linktext) = explode('|', $link[0]); if($this->getConf('rel_links')) $current_id = $this->abs2rel($link_id,$ID); else $current_id = $link_id; //like in _getLinkTitle in xhtml.php if(useHeading('content')) { $tmp_linktext = p_get_first_heading($link_id); if(trim($linktext) == trim($tmp_linktext)) { $linktext = ""; } } $tmp_ar = explode(':',$link_id); $tmp_id = array_pop($tmp_ar); if(trim($linktext,'.: ' ) == trim($tmp_id,'.: ')) $linktext = ""; $current_id = $current_id.'|'.$linktext; return '[[' . $current_id .']]'; }, $TEXT ); if($this->getConf('rel_links')) { $TEXT = preg_replace_callback( '#\{\{(\s*)(.*?)(\s*)\}\}#ms', function($matches) { global $ID; $link = explode('?',$matches[2]); list($link_id,$linktext) = explode('|', $link[0]); $rel = $this->abs2rel($link_id,$ID); if(!empty($link[1])) $rel .= '?' . $link[1]; if(!empty($linktext)) $rel = $rel.'|'.$linktext; return '{{' .$matches[1] . $rel . $matches[3] .'}}'; }, $TEXT ); } /* 11 Dec 2013 see comment below Remove discarded font syntax */ $TEXT = preg_replace_callback( '|_REMOVE_FONTS_START_(.*?)_REMOVE_FONTS_END_|ms', create_function( '$matches', '$matches[1] = preg_replace("//ms","",$matches[1]); return preg_replace("/<\/font>/ms","",$matches[1]);' ), $TEXT ); /* 6 April 2013 Removed newlines and spaces from beginnings and ends of text enclosed by font tags. Too subtle for javascript. */ $TEXT = preg_replace_callback( '|()(.*?)(?=)|ms', create_function( '$matches', '$matches[2]=preg_replace("/^\s+/ms","",$matches[2]); $matches[2]=preg_replace("/\s+$/ms","",$matches[2]); return $matches[1]. $matches[2];' ), $TEXT ); $TEXT = preg_replace('/__QUOTE__/ms',">",$TEXT); $TEXT = preg_replace('/[\t\x20]+$/ms',"",$TEXT); $TEXT = preg_replace('/\n{4,}/ms',"\n\n",$TEXT); $TEXT = preg_replace('/\n{3,}/ms',"\n\n",$TEXT); /*first pass for blockquotes*/ $TEXT = preg_replace_callback( "#^>+(.*?)\\\\\\\\#ms", function($matches) { return str_replace('\\',"",$matches[0]); }, $TEXT ); /* remove extra line-feeds following in-table code blocks make sure cell-ending pipe not mistaken for a following link divider */ $TEXT = preg_replace_callback( '#(/code|/file)\>.*?\n\|#ms', function($matches) { $matches[0] = preg_replace("/([\S\s\w\:])\\\\\\\\(\w)/ms","$1@#@$2",$matches[0]); //retain backslashes inside code blocks $matches[0] = preg_replace("/(\w+)\\\\\\\\(\w)/ms","$1@#@",$matches[0]); $matches[0] = preg_replace("/\\\\(\w+)/ms","@!@$1",$matches[0]); $matches[0] = preg_replace("/(\w+)\\\\/ms","@!@$1",$matches[0]); $matches[0] = str_replace("\\", "",$matches[0]); $matches[0] = str_replace("@!@",'\\',$matches[0]); return str_replace("@#@", "\\\\",$matches[0]); }, $TEXT ); /* reformat table cell after removing extra line-feeds, above */ $TEXT = preg_replace_callback( '#\|[\s\n]+(\)(.*?)(\<\/file>\s*.*?)\n?\|#ms', function($matches) { $matches[3] = preg_replace('/\n+/',"",$matches[3] ); $matches[3] = preg_replace('/\s+$/',"",$matches[3] ) . '|'; return '|' . $matches[1] . $matches[2] . str_replace("\\ ","",$matches[3]); }, $TEXT ); return; } function replace_entities() { global $TEXT; global $ents; $serialized = FCK_ACTION_SUBDIR . 'ent.ser'; $ents = unserialize(file_get_contents($serialized)); $TEXT = preg_replace_callback( '|(&(\w+);)|', create_function( '$matches', 'global $ents; return $ents[$matches[2]];' ), $TEXT ); } function write_debug($data) { return; if (!$handle = fopen('save.txt', 'a')) { return; } // Write $somecontent to our opened file. fwrite($handle, "save.php: $data\n"); fclose($handle); } /* @auth Sergey Kotov */ //linkPath is the link in the page //pagePath is absolute path of the page (ns1:ns2:....:page or :ns1:ns2:....:page) function abs2rel($linkPath,$pagePath){ if ($linkPath[0]==='.'){ // It's already relative return $linkPath; } $aLink=explode(':',$linkPath); $nLink=count($aLink); if ($nLink<2){ return $linkPath; } $aPage=explode(':',$pagePath); if(empty($aLink[0])) { // If linkPath is started by ':' // Make canonical absolute path ns1:ns2:.....:pageLink (strip leading :) array_shift($aLink); if (--$nLink<2) { return $linkPath; } } if(empty($aPage[0])) { // If pagePath is started by ':' // Make canonical absolute path ns1:ns2:.....:page (strip leading :) array_shift($aPage); } $nPage=count($aPage); $nslEqual=0; // count of equal namespaces from left to right // Minimal length of these two arrays, page name is not included $nMin=($nLink<$nPage ? $nLink : $nPage)-1 ; for ($i=0;$i<$nMin;++$i){ if ($aLink[$i]===$aPage[$i]){ ++$nslEqual; } else { break; } } if ($nslEqual==0){ // Link and page from different root namespaces return $linkPath; } // Truncate equal lef namespaces $aPageDiff=array_slice($aPage,$nslEqual); $nPageDiff=count($aPageDiff); $aLinkDiff=array_slice($aLink,$nslEqual); // Now we have to go up to nPageDiff-1 levels $aResult=array(); if ($nPageDiff>1){ $aResult=array_fill(0,$nPageDiff-1,'..'); } else if($nPageDiff == 1) { $aResult[] = '.'; } $aResult=array_merge($aResult,$aLinkDiff); return implode(':', $aResult); } } //end of action class ?>