/** * @param string $path file path of less file to compile * @param string $topath file path of output css file * @return bool|mixed compile result or the css compiled content */ public static function compileCss($path, $topath = '', $split = false, $list = null) { $fromdir = dirname($path); $app = JFactory::getApplication(); $is_rtl = $app->getUserState('current_direction') == 'rtl'; if (empty($list)) { $list = self::parse($path); } if (empty($list)) { return false; } // join $list $content = ''; $importdirs = array(); $todir = $topath ? dirname($topath) : $fromdir; if (!is_dir(JPATH_ROOT . '/' . $todir)) { JFolder::create(JPATH_ROOT . '/' . $todir); } $importdirs[JPATH_ROOT . '/' . $fromdir] = self::relativePath($todir, $fromdir); foreach ($list as $f => $import) { if ($import) { $importdirs[JPATH_ROOT . '/' . dirname($f)] = self::relativePath($todir, dirname($f)); $content .= "\n#" . self::$kfilepath . "{content: \"{$f}\";}\n"; // $content .= "@import \"$import\";\n\n"; if (is_file(JPATH_ROOT . '/' . $f)) { $less_content = file_get_contents(JPATH_ROOT . '/' . $f); // remove vars/mixins for template & canvas less if (preg_match('@' . preg_quote(CANVAS_TEMPLATE_REL, '@') . '/less/@i', $f) || preg_match('@' . preg_quote(CANVAS_REL, '@') . '/less/@i', $f)) { $less_content = preg_replace(self::$rimportvars, '', $less_content); } self::$_path = CANVASPath::relativePath($fromdir, dirname($f)) . '/'; $less_content = preg_replace_callback(self::$rimport, array('CANVASLess', 'cb_import_path'), $less_content); $content .= $less_content; } } else { $content .= "\n#" . self::$kfilepath . "{content: \"{$path}\";}\n"; $content .= $f . "\n\n"; } } // get vars $vars_files = explode('|', self::getVars('urls')); // build source $source = ''; // build import vars foreach ($vars_files as $var) { $vars_path = CANVASPath::relativePath($fromdir, dirname($var)); if ($vars_path) { $vars_path .= "/"; } $var_file = $vars_path . basename($var); $source .= "@import \"" . $var_file . "\";\n"; } // less content $source .= "\n#" . self::$kvarsep . "{content: \"separator\";}\n" . $content; // call Less to compile $output = CANVASLessCompiler::compile($source, $path, $todir, $importdirs); // process content //use cssjanus to transform the content if ($is_rtl) { $output = preg_split(self::$rsplitbegin . self::$krtlsep . self::$rsplitend, $output, -1, PREG_SPLIT_DELIM_CAPTURE); $rtlcontent = isset($output[2]) ? $output[2] : false; $output = $output[0]; CANVAS::import('jacssjanus/ja.cssjanus'); $output = JACSSJanus::transform($output, true); // join with rtl content if ($rtlcontent) { $output = $output . "\n" . $rtlcontent; } } // skip duplicate clearfix $arr = preg_split(self::$rsplitbegin . self::$kvarsep . self::$rsplitend, $output, 2); if (preg_match('/bootstrap.less/', $path)) { $output = implode("\n", $arr); } else { $output = count($arr) > 1 ? $arr[1] : $arr[0]; } //remove comments and clean up $output = preg_replace(self::$rcomment, '', $output); $output = preg_replace(self::$rspace, "\n\n", $output); // split if needed if ($split) { //update path and store to files $split_contents = preg_split(self::$rsplitbegin . self::$kfilepath . self::$rsplitend, $output, -1, PREG_SPLIT_DELIM_CAPTURE); $file_contents = array(); $file = $path; $isfile = false; foreach ($split_contents as $chunk) { if ($isfile) { $isfile = false; $file = $chunk; } else { $file_contents[$file] = (isset($file_contents[$file]) ? $file_contents[$file] : '') . "\n" . $chunk . "\n\n"; $isfile = true; } } if (!empty($file_contents)) { //output the file to content and add to document foreach ($file_contents as $file => $content) { $content = trim($content); $filename = str_replace('/', '.', $file) . '.css'; JFile::write(JPATH_ROOT . '/' . $todir . '/' . $filename, $content); } } } else { $output = preg_replace(self::$rsplitbegin . self::$kfilepath . self::$rsplitend, '', $output); $output = trim($output); if ($topath) { JFile::write(JPATH_ROOT . '/' . $topath, $output); } else { return $output; } } // write to path return true; }