From 5fd62690ddd49c0ed7a7ef0ed8ac761cad2dc21a Mon Sep 17 00:00:00 2001
From: Myron Turner
Date: Wed, 15 May 2019 08:44:44 -0500
Subject: [PATCH] Usr styles (#475)
* additons for creating user styles
* updates to admin.php
* Updates admin.php to accept input for alternate template
* Set up path to alternate template
* new message function; tied alternate template to css6
* Replace text input with drop-down menu list for selecting alternate templates
* removed non-writable directories from template drop-down list
* Adds option to copy of default _style.css to ckeditor/css
* Adding setting for using alternate style sheet.
* adds info to aadmin.php
* Includes function alt_style_sheet() in edit.php to check for alternate style sheet in ckeditor/css.
* Chagned function name tfunc to ckg_admininfo, proof against naming ocnflicts
* fix for compressed files which remove comments, hence header with template name from _style.css
* Localization for Info button in admin.php, enabling exact comparison for toggle function ckg_admininfo
---
action/edit.php | 40 +++-
admin.php | 124 ++++++++++
conf/default.php | 3 +
conf/metadata.php | 3 +-
lang/en/lang.php | 12 +-
lang/en/settings.php | 3 +
lang/en/style.txt | 11 +
script.js | 5 +
scripts/css6.php | 533 +++++++++++++++++++++++++++++++++++++++++++
9 files changed, 729 insertions(+), 5 deletions(-)
create mode 100755 admin.php
create mode 100755 lang/en/style.txt
create mode 100644 scripts/css6.php
diff --git a/action/edit.php b/action/edit.php
index 5d9b3c4f..e710116b 100755
--- a/action/edit.php
+++ b/action/edit.php
@@ -517,6 +517,30 @@ function dw_edit_displayed()
}
+ /**
+ Check for for alternate style sheet
+ */
+ function alt_style_sheet() {
+ $stylesheet = DOKU_PLUGIN . 'ckgedit/ckeditor/css/_style.css';
+ if(file_exists($stylesheet)) {
+ global $conf;
+ $tpl_name = $conf['template'];
+ if($fh = fopen($stylesheet,"r")) {
+ $line_num = 0;
+ while (!feof($fh) && $line_num < 4) {
+ $line = fgets($fh,1024); //msg($line);
+ if(strpos($line,$tpl_name)!==false) {
+ return DOKU_BASE . '/lib/plugins/ckgedit/ckeditor/css/_style.css' ;
+ break;
+ }
+ $line_num ++;
+ }
+ }
+ }
+ return "";
+ }
+
+
/**
* function _print
* @author Myron Turner
@@ -586,7 +610,8 @@ function _print()
$fbOptions = "filebrowserImageBrowseUrl : \"$doku_url/lib/plugins/ckgedit/fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=$doku_url/lib/plugins/ckgedit/fckeditor/editor/filemanager/connectors/php/connector.php\",
filebrowserBrowseUrl: \"$doku_url/lib/plugins/ckgedit/fckeditor/editor/filemanager/browser/default/browser.html?Type=File&Connector=$doku_url/lib/plugins/ckgedit/fckeditor/editor/filemanager/connectors/php/connector.php\"";
}
-
+$contents_css = $this->alt_style_sheet();
+//msg($contents_css);
$ckeditor_replace =<<
+xhtml=<<go to top | back to Index | Wiki start page ]
+ERRTXT;*/
+?>
-
+
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+*/
+
+require_once(DOKU_INC . 'lib/plugins/ckgedit/scripts/css6.php');
+class admin_plugin_ckgedit extends DokuWiki_Admin_Plugin {
+
+ private $tpl_inc;
+ private $template;
+ private $alt;
+ function __construct() {
+ global $conf;
+ $this->template = $conf['template'];
+ $this->tpl_inc = tpl_incdir();
+ }
+
+ function handle() {
+
+ if (!isset($_REQUEST['cmd'])) return; // first time - nothing to do
+
+ $this->output = 'invalid';
+
+ if (!checkSecurityToken()) return;
+ if (!is_array($_REQUEST['cmd'])) return;
+
+ switch (key($_REQUEST['cmd'])) {
+ case 'stylesheet' : {
+ $this->alt = "";
+ $this->output = 'style_sheet_msg';
+ break;
+ }
+ case 'alt_stylesheet' : {
+ $this->alt = $_REQUEST['templates'];
+ $this->output = 'alt_style_sheet_msg';
+ break;
+ }
+ }
+
+
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+ ptln('');
+ echo $this->locale_xhtml('style');
+ ptln('
');
+ ptln('');
+
+ ptln('
');
+
+ if($this->output && $this->output == 'style_sheet_msg') {
+ $path = $this->tpl_inc;
+ ptln(htmlspecialchars($this->getLang($this->output)). " " .$this->template);
+ $retv = css_ckg_out($path);
+ $this->message($path, $retv);
+
+ }
+ else if($this->output && $this->output == 'alt_style_sheet_msg') {
+ ptln(htmlspecialchars($this->getLang($this->output)). " " .$this->alt);
+ $path = str_replace('tpl/'.$this->template, 'tpl/'.$this->alt,$this->tpl_inc);
+ $retv = css_ckg_out($path,$this->alt);
+ $this->message($path, $retv);
+ }
+
+ }
+
+ function message($path, $which) {
+ $messages = array(
+ "Stylesheet saved to $path" . 'Styles/_style.css',
+ "Failed to save stylesheet to $path" . 'Styles/_style.css'
+ );
+ $color = $which == 0? '#333': 'blue';
+ ptln('
'.htmlspecialchars($messages[$which]).'');
+
+ }
+
+ function templates($selected="") {
+ $dir = dirname($this->tpl_inc);
+ $files = scandir($dir);
+ $dir .= '/';
+ $list = "";
+ foreach ($files AS $file) {
+ if($file == '.' || $file == '..' || $file == $this->template) continue;
+ $entry = $dir . $file;
+ if(!is_writable($entry)) continue;
+ if(is_dir ($entry ) ) {
+ if($file == $selected) {
+ $list .= "";
+ }
+ else $list .= "";
+ }
+ }
+
+ return $list;
+ }
+}
\ No newline at end of file
diff --git a/conf/default.php b/conf/default.php
index 4973a50b..a27f5115 100644
--- a/conf/default.php
+++ b/conf/default.php
@@ -40,5 +40,8 @@
$conf['preserve_enc'] = 0;
$conf['gui'] = 'moono';
$conf['rel_links'] = 0;
+$conf['style_sheet'] = 0;
+
+
diff --git a/conf/metadata.php b/conf/metadata.php
index 4147bedf..12b79159 100644
--- a/conf/metadata.php
+++ b/conf/metadata.php
@@ -42,4 +42,5 @@
$meta['dblclk'] = array('multichoice','_choices' => array('on','off'));
$meta['preserve_enc'] = array('onoff');
$meta['gui'] = array('multichoice','_choices' => array('moono','moono-lisa'));
-$meta['rel_links'] = array('onoff');
\ No newline at end of file
+$meta['rel_links'] = array('onoff');
+$meta['style_sheet']= array('onoff');
diff --git a/lang/en/lang.php b/lang/en/lang.php
index d283af31..dafadc08 100755
--- a/lang/en/lang.php
+++ b/lang/en/lang.php
@@ -65,5 +65,15 @@
$lang['broken_image'] = "Use the imagePaste plugin with the Dokuwiki Mediamanager or try the MS Word Paste Tool. Raw data of Ctrl-v images over 2.5M can hang. This image is: " ;
$lang['js']['broken_image_1'] = "Use the imagePaste plugin with the Dokuwiki Mediamanager or try the MS Word Paste Tool.";
$lang['js']['broken_image_2'] = "Ctrl-v images with raw data over 2.5M can hang. This image is: " ;
-
+$lang['menu'] = 'CKEditor editor CSS tool';
+$lang['default_stylesheet'] = 'Create a style sheet for the current template';
+$lang['alt_stylesheet'] = 'Create a stylesheet for another template';
+$lang['style_sheet'] = 'Create Style sheet';
+$lang['style_sheet_msg'] = 'Creating Style sheet for the current template:';
+$lang['alt_style_sheet_msg'] = 'Creating Style sheet for:';
+$lang['checkbox'] = 'Copy to ckeditor/css';
+$lang['stylesheet_oinfo'] = 'Info';
+$lang['stylesheet_cinfo'] = 'Close Info';
+$lang['js']['stylesheet_oinfo'] = $lang['stylesheet_oinfo'];
+$lang['js']['stylesheet_cinfo'] = $lang['stylesheet_cinfo'];
diff --git a/lang/en/settings.php b/lang/en/settings.php
index f499e3ea..13278a53 100755
--- a/lang/en/settings.php
+++ b/lang/en/settings.php
@@ -51,4 +51,7 @@
$lang['preserve_enc'] ="Preserve urlencoding in urls when the dokuwiki deaccent option is active.";
$lang['gui'] = "Select CKEditor GUI.";
$lang['rel_links'] = "Activate support for relative internal and image links";
+$lang['style_sheet'] = 'Use an alternate style sheet for the Ckeditor editing window.' .
+ ' For more information see the CKEditor editor CSS tool, under Additional Plugins on the Admin
page. Or ' .
+ ' see the ckgedit plugin page.';
diff --git a/lang/en/style.txt b/lang/en/style.txt
new file mode 100755
index 00000000..aac34bcf
--- /dev/null
+++ b/lang/en/style.txt
@@ -0,0 +1,11 @@
+**Current Template** \\
+With this app you can create a style sheet for the CKEditor's editing window that is based on your template. It will place the style sheet in your template folder in the directory named **Styles**, which will be created when the style sheet is saved. The style sheet will be named **_styles.css**. To activate this style sheet two things must be done:
+
+ - it must be placed in **ckgedit/ckeditor/css**. This will automatically be done for you if you check off the checkbox labeled **Copy to ckeditor/css.**
+ - The **style_sheet** option in the ''Configuration Settings'' must be set to **true**.
+
+**Other templates: installed but not activate** \\ You can also create additional style sheets for other templates which you might have stored in your **tpl** folder. These will be copied to the Styles folder of the respective templates but not to **ckeditor/css**.
+
+----
+
+
diff --git a/script.js b/script.js
index f488eba5..36d9d449 100644
--- a/script.js
+++ b/script.js
@@ -487,3 +487,8 @@ function getCookie(name) {
var value = re.exec(document.cookie);
return (value != null) ? decodeURIComponent(value[1]) : null;
}
+function ckg_admininfo(t){
+ if(t.innerHTML == LANG.plugins.ckgedit.stylesheet_cinfo)
+ t.innerHTML = LANG.plugins.ckgedit.stylesheet_oinfo;
+ else t.innerHTML = LANG.plugins.ckgedit.stylesheet_cinfo;
+}
\ No newline at end of file
diff --git a/scripts/css6.php b/scripts/css6.php
new file mode 100644
index 00000000..04bad85a
--- /dev/null
+++ b/scripts/css6.php
@@ -0,0 +1,533 @@
+
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../../').'/');
+require_once(DOKU_INC.'inc/init.php');
+
+// ---------------------- functions ------------------------------
+
+/**
+ * Output all needed Styles
+ *
+ * @author Andreas Gohr
+ */
+function css_ckg_out($path, $tpl = "")
+{
+ global $conf;
+ global $lang;
+ global $config_cascade;
+ global $INPUT;
+ $copy = $INPUT->str('ckg_save_ss',FALSE);
+
+ chdir($path);
+
+ $mediatypes = array('screen', 'all');
+ $type = '';
+
+ if(!$tpl) {
+ $tpl = $conf['template'];
+
+ if($copy) {
+ $copy_path = DOKU_PLUGIN . 'ckgedit/ckeditor/css/_style.css';
+ msg($copy_path,1);
+ }
+ }
+
+ // load styl.ini
+ $styleini = css_ckg_styleini($tpl);
+
+ // if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility
+ if (isset($config_cascade['userstyle']['default'])) {
+ $config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default'];
+ }
+
+ // Array of needed files and their web locations, the latter ones
+ // are needed to fix relative paths in the stylesheets
+ $files = array();
+ foreach($mediatypes as $mediatype) {
+ $files[$mediatype] = array();
+ // load core styles
+ $files[$mediatype][DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/';
+
+ // load template styles
+ if (isset($styleini['stylesheets'][$mediatype])) {
+ $files[$mediatype] = array_merge($files[$mediatype], $styleini['stylesheets'][$mediatype]);
+ }
+ // load user styles
+ if(!empty($config_cascade['userstyle'][$mediatype])) {
+ foreach($config_cascade['userstyle'][$mediatype] as $userstyle) {
+ $files[$mediatype][$userstyle] = DOKU_BASE;
+ }
+ }
+ }
+
+
+
+ $css="";
+
+ // build the stylesheet
+ foreach ($mediatypes as $mediatype) {
+
+ // print the default classes for interwiki links and file downloads
+ if ($mediatype == 'screen') {
+ $css .= '@media screen {';
+ css_ckg_interwiki($css);
+ css_ckg_filetypes($css);
+ $css .= '}';
+ }
+
+
+//$xcl = 'plugins/popularity|usermanager|plugins/upgrade|plugins/acl|plugins/plugin|plugins/auth|plugins/config|plugins/revert|_imgdetail.css'
+$xcl = 'plugins|popup|fileuploader|toc|search|recent|diff|edit|form|admin|manager|media|modal';
+
+
+
+ // load files
+ $css_ckg_content = '';
+ foreach($files[$mediatype] as $file => $location){
+ if(preg_match('#' .$xcl . '#',$file)) {
+ continue;
+ }
+ $display = str_replace(fullpath(DOKU_INC), '', fullpath($file));
+ $css_ckg_content .= "\n/* XXXXXXXXX $display XXXXXXXXX */\n";
+ $css_ckg_content .= css_ckg_loadfile($file, $location);
+ }
+ switch ($mediatype) {
+ case 'screen':
+ $css .= NL.'@media screen { /* START screen styles */'.NL.$css_ckg_content.NL.'} /* /@media END screen styles */'.NL;
+ break;
+ case 'all':
+ default:
+ $css .= NL.'/* START rest styles */ '.NL.$css_ckg_content.NL.'/* END rest styles */'.NL;
+ break;
+ }
+ }
+
+ // apply style replacements
+ $css = css_ckg_applystyle($css, $styleini['replacements']);
+
+
+
+ // parse less
+ $css = css_ckg_parseless($css);
+
+ // embed small images right into the stylesheet
+ if($conf['cssdatauri']){
+ $base = preg_quote(DOKU_BASE,'#');
+ $css = preg_replace_callback('#(url\([ \'"]*)('.$base.')(.*?(?:\.(png|gif)))#i','css_ckg_datauri',$css);
+ }
+
+ // echo $path . "Styles/_style.css\n";
+
+ $css = preg_replace("/(\#?|\.?|div\.)dokuwiki\.?/", '', $css);
+ $css = "/* template: $tpl */\n@media screen {\n.$tpl{color:#ccc;}\n}\n" . $css;
+ $css .= '
+ span.multi_p_open {
+ display: block;
+ }
+ body,html {
+ background-color: #fff;
+ background-image:none;
+}
+' . "\n";
+
+ if( io_saveFile($path . 'Styles/_style.css' ,$css)) {
+ if(isset($copy_path)) { ;
+ $retv = io_saveFile($copy_path,$css);
+ if(!$retv) msg("failed: " . $copy_path);
+ }
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+/**
+ * Uses phpless to parse LESS in our CSS
+ *
+ * most of this function is error handling to show a nice useful error when
+ * LESS compilation fails
+ *
+ * @param $css
+ * @return string
+ */
+function css_ckg_parseless($css) {
+ $less = new lessc();
+ $less->importDir[] = DOKU_INC;
+
+ try {
+ return $less->compile($css);
+ } catch(Exception $e) {
+ // get exception message
+ $msg = str_replace(array("\n", "\r", "'"), array(), $e->getMessage());
+
+ // try to use line number to find affected file
+ if(preg_match('/line: (\d+)$/', $msg, $m)){
+ $msg = substr($msg, 0, -1* strlen($m[0])); //remove useless linenumber
+ $lno = $m[1];
+
+ // walk upwards to last include
+ $lines = explode("\n", $css);
+ for($i=$lno-1; $i>=0; $i--){
+ if(preg_match('/\/(\* XXXXXXXXX )(.*?)( XXXXXXXXX \*)\//', $lines[$i], $m)){
+ // we found it, add info to message
+ $msg .= ' in '.$m[2].' at line '.($lno-$i);
+ break;
+ }
+ }
+ }
+
+ // something went wrong
+ $error = 'A fatal error occured during compilation of the CSS files. '.
+ 'If you recently installed a new plugin or template it '.
+ 'might be broken and you should try disabling it again. ['.$msg.']';
+
+ msg($error);
+
+ exit;
+ }
+}
+
+/**
+ * Does placeholder replacements in the style according to
+ * the ones defined in a templates style.ini file
+ *
+ * This also adds the ini defined placeholders as less variables
+ * (sans the surrounding __ and with a ini_ prefix)
+ *
+ * @author Andreas Gohr
+ */
+function css_ckg_applystyle($css, $replacements) {
+ // we convert ini replacements to LESS variable names
+ // and build a list of variable: value; pairs
+ $less = '';
+ foreach((array) $replacements as $key => $value) {
+ $lkey = trim($key, '_');
+ $lkey = '@ini_'.$lkey;
+ $less .= "$lkey: $value;\n";
+
+ $replacements[$key] = $lkey;
+ }
+
+ // we now replace all old ini replacements with LESS variables
+ $css = strtr($css, $replacements);
+
+ // now prepend the list of LESS variables as the very first thing
+ $css = $less.$css;
+ return $css;
+}
+
+/**
+ * Load style ini contents
+ *
+ * Loads and merges style.ini files from template and config and prepares
+ * the stylesheet modes
+ *
+ * @author Andreas Gohr
+ * @param string $tpl the used template
+ * @return array with keys 'stylesheets' and 'replacements'
+ */
+function css_ckg_styleini($tpl) {
+ $stylesheets = array(); // mode, file => base
+ $replacements = array(); // placeholder => value
+
+ // load template's style.ini
+ $incbase = tpl_incdir($tpl);
+ $webbase = tpl_basedir($tpl);
+ $ini = $incbase.'style.ini';
+ if(file_exists($ini)){
+ $data = parse_ini_file($ini, true);
+
+ // stylesheets
+ if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){
+ $stylesheets[$mode][$incbase.$file] = $webbase;
+ }
+
+ // replacements
+ if(is_array($data['replacements'])){
+ $replacements = array_merge($replacements, css_ckg_fixreplacementurls($data['replacements'],$webbase));
+ }
+ }
+
+ // load configs's style.ini
+ $webbase = DOKU_BASE;
+ $ini = DOKU_CONF."tpl/$tpl/style.ini";
+ $incbase = dirname($ini).'/';
+ if(file_exists($ini)){
+ $data = parse_ini_file($ini, true);
+
+ // stylesheets
+ if(isset($data['stylesheets']) && is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){
+ $stylesheets[$mode][$incbase.$file] = $webbase;
+ }
+
+ // replacements
+ if(isset($data['replacements']) && is_array($data['replacements'])){
+ $replacements = array_merge($replacements, css_ckg_fixreplacementurls($data['replacements'],$webbase));
+ }
+ }
+
+ return array(
+ 'stylesheets' => $stylesheets,
+ 'replacements' => $replacements
+ );
+}
+
+/**
+ * Amend paths used in replacement relative urls, refer FS#2879
+ *
+ * @author Chris Smith
+ */
+function css_ckg_fixreplacementurls($replacements, $location) {
+ foreach($replacements as $key => $value) {
+ $replacements[$key] = preg_replace('#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#','\\1'.$location,$value);
+ }
+ return $replacements;
+}
+
+/**
+ * Prints classes for interwikilinks
+ *
+ * Interwiki links have two classes: 'interwiki' and 'iw_$name>' where
+ * $name is the identifier given in the config. All Interwiki links get
+ * an default style with a default icon. If a special icon is available
+ * for an interwiki URL it is set in it's own class. Both classes can be
+ * overwritten in the template or userstyles.
+ *
+ * @author Andreas Gohr
+ */
+function css_ckg_interwiki(&$css){
+
+ // default style
+ $css .= 'a.interwiki {';
+ $css .= ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.png) 0px 1px no-repeat;';
+ $css .= ' padding: 1px 0px 1px 16px;';
+ $css .= '}';
+
+ // additional styles when icon available
+ $iwlinks = getInterwiki();
+ foreach(array_keys($iwlinks) as $iw){
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$iw);
+ if(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.png')){
+ $css .= "a.iw_$class {";
+ $css .= ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.png)';
+ $css .= '}';
+ }elseif(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.gif')){
+ $css .= "a.iw_$class {";
+ $css .= ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.gif)';
+ $css .= '}';
+ }
+ }
+}
+
+/**
+ * Prints classes for file download links
+ *
+ * @author Andreas Gohr
+ */
+function css_ckg_filetypes(&$css){
+
+ // default style
+ $css .= '.mediafile {';
+ $css .= ' background: transparent url('.DOKU_BASE.'lib/images/fileicons/file.png) 0px 1px no-repeat;';
+ $css .= ' padding-left: 18px;';
+ $css .= ' padding-bottom: 1px;';
+ $css .= '}';
+
+ // additional styles when icon available
+ // scan directory for all icons
+ $exts = array();
+ if($dh = opendir(DOKU_INC.'lib/images/fileicons')){
+ while(false !== ($file = readdir($dh))){
+ if(preg_match('/([_\-a-z0-9]+(?:\.[_\-a-z0-9]+)*?)\.(png|gif)/i',$file,$match)){
+ $ext = strtolower($match[1]);
+ $type = '.'.strtolower($match[2]);
+ if($ext!='file' && (!isset($exts[$ext]) || $type=='.png')){
+ $exts[$ext] = $type;
+ }
+ }
+ }
+ closedir($dh);
+ }
+ foreach($exts as $ext=>$type){
+ $class = preg_replace('/[^_\-a-z0-9]+/','_',$ext);
+ $css .= ".mf_$class {";
+ $css .= ' background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.$type.')';
+ $css .= '}';
+ }
+}
+
+/**
+ * Loads a given file and fixes relative URLs with the
+ * given location prefix
+ */
+function css_ckg_loadfile($file,$location=''){
+ $css_ckg_file = new DokuCssFile($file);
+ return $css_ckg_file->load($location);
+}
+
+/**
+ * Helper class to abstract loading of css/less files
+ *
+ * @author Chris Smith
+ */
+class DokuCssFile {
+
+ protected $filepath; // file system path to the CSS/Less file
+ protected $location; // base url location of the CSS/Less file
+ private $relative_path = null;
+
+ public function __construct($file) {
+ $this->filepath = $file;
+ }
+
+ /**
+ * Load the contents of the css/less file and adjust any relative paths/urls (relative to this file) to be
+ * relative to the dokuwiki root: the web root (DOKU_BASE) for most files; the file system root (DOKU_INC)
+ * for less files.
+ *
+ * @param string $location base url for this file
+ * @return string the CSS/Less contents of the file
+ */
+ public function load($location='') {
+ if (!file_exists($this->filepath)) return '';
+
+ $css = io_readFile($this->filepath);
+ if (!$location) return $css;
+
+ $this->location = $location;
+
+ $css = preg_replace_callback('#(url\( *)([\'"]?)(.*?)(\2)( *\))#',array($this,'replacements'),$css);
+ $css = preg_replace_callback('#(@import\s+)([\'"])(.*?)(\2)#',array($this,'replacements'),$css);
+
+ return $css;
+ }
+
+ /**
+ * Get the relative file system path of this file, relative to dokuwiki's root folder, DOKU_INC
+ *
+ * @return string relative file system path
+ */
+ private function getRelativePath(){
+
+ if (is_null($this->relative_path)) {
+ $basedir = array(DOKU_INC);
+
+ $basedir = array_map('preg_quote_cb', $basedir);
+ $regex = '/^('.join('|',$basedir).')/';
+ $this->relative_path = preg_replace($regex, '', dirname($this->filepath));
+ }
+
+ return $this->relative_path;
+ }
+
+ /**
+ * preg_replace callback to adjust relative urls from relative to this file to relative
+ * to the appropriate dokuwiki root location as described in the code
+ *
+ * @param array see http://php.net/preg_replace_callback
+ * @return string see http://php.net/preg_replace_callback
+ */
+ public function replacements($match) {
+
+ // not a relative url? - no adjustment required
+ if (preg_match('#^(/|data:|https?://)#',$match[3])) {
+ return $match[0];
+ }
+ // a less file import? - requires a file system location
+ else if (substr($match[3],-5) == '.less') {
+ if ($match[3]{0} != '/') {
+ $match[3] = $this->getRelativePath() . '/' . $match[3];
+ }
+ }
+ // everything else requires a url adjustment
+ else {
+ $match[3] = $this->location . $match[3];
+ }
+
+ return join('',array_slice($match,1));
+ }
+}
+
+/**
+ * Convert local image URLs to data URLs if the filesize is small
+ *
+ * Callback for preg_replace_callback
+ */
+function css_ckg_datauri($match){
+ global $conf;
+
+ $pre = unslash($match[1]);
+ $base = unslash($match[2]);
+ $url = unslash($match[3]);
+ $ext = unslash($match[4]);
+
+ $local = DOKU_INC.$url;
+ $size = @filesize($local);
+ if($size && $size < $conf['cssdatauri']){
+ $data = base64_encode(file_get_contents($local));
+ }
+ if($data){
+ $url = 'data:image/'.$ext.';base64,'.$data;
+ }else{
+ $url = $base.$url;
+ }
+ return $pre.$url;
+}
+
+
+
+/**
+ * Very simple CSS optimizer
+ *
+ * @author Andreas Gohr
+ */
+function css_ckg_compress($css){
+ //strip comments through a callback
+ $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s','css_ckg_comment_cb',$css);
+
+ //strip (incorrect but common) one line comments
+ $css = preg_replace('/(? 1em)
+ $css = preg_replace('/(?
+ */
+function css_ckg_comment_cb($matches){
+ if(strlen($matches[2]) > 4) return '';
+ return $matches[0];
+}
+//global $conf ;
+//css_ckg_out('/home/www/html/devel/lib/tpl/' . $conf['template'] .'/');
+