Source: flipcss.phps - download
<?php
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* flipcss.php 0.9.2
* by Daif Alazmi (http://daif.net)
* daif@daif.net
*
* Link:
* http://daif.net/flipcss/flipcss.phps
*
* Description:
* This Tool flip CSS rules direction from LTR to RTL or vice versa .
* tool support these CSS rules: float, text-align, padding, margin
* and border-radius .
*
* Syntax:
* right to left
* $flip = new FlipCSS();
* $rtl_css = $flip->parseCSS($css_data, 'RTL', array('.pull-right', '.pull-left'));
* left to right
* $flip = new FlipCSS();
* $ltr_css = $flip->parseCSS($css_data, 'LTR', array('.pull-right', '.pull-left'));
*
* Changelog
* 0.1 first release
* 0.2 rewrite padding and margin
* 0.3 support border-radius
* 0.4 added GPL License
* 0.5 support border
* 0.6 fix issue with rewrite padding,margin,border Regex
* 0.7 added the $escaped parameter
* 0.8 some code improvement
* 0.9 fix parsing issue with two braces like @media , @-*
* 0.9.1 ignore escape array it is count zero.
* 0.9.2 fix parsing left and right if not start with spaces.
*/
class FlipCSS{
/**
* version number
*
* @var string
*/
public $version = '0.9.2';
/**
* CSS content
*
* @var string
*/
public $css_data;
/**
* flipped CSS content
*
* @var string
*/
public $css_flipped;
/**
* CSS ignored class name
*
* @var array
*/
public $escaped = array('.pull-right','.pull-left','.text-left','.text-right','.left','.right');
/**
* Parse the CSS data
*
* @param string
* @param string
* @param array
* @return string
*/
public function parseCSS($css_data, $dir='RTL', $escaped=array()) {
$this->css_data = $css_data;
//set Generated by message
$this->css_flipped = "/* Generated by flipcss.php ".$this->version.
" (http://flipcss.com/) */\nbody{\n direction:$dir;\n}\n\n";
// remove comments
$this->css_data = preg_replace('/\*\//',"*/\n" ,$this->css_data);
$this->css_data = preg_replace('/\/\*(.*)?\*\//Usi','' ,$this->css_data);
//remove @charset
$this->css_data = preg_replace('/@charset .+;/Ui',"", $this->css_data);
// try to unminify minified css
$this->css_data = preg_replace('/{/'," {\n", $this->css_data);
$this->css_data = preg_replace('/}/',"\n}\n", $this->css_data);
$this->css_data = preg_replace('/;/',";\n", $this->css_data);
$this->css_data = preg_replace('/,/',",\n", $this->css_data);
// rewrite padding,margin,border
$this->css_data = preg_replace('/(\h*)(padding|margin|border)\h*:\h*(\d+.*)\h+(\d+.*)\h+(\d+.*)\h+(\d+.*)\h*;/Ui',
"\\1\\2-right:\\4;\n\\1\\2-left:\\6;\n" ,$this->css_data);
// rewrite border-radius
$this->css_data = preg_replace('/(\h*|)border-radius:(.+)\h+(.+)\h+(.+)\h+(.+)\h*;/Ui',"\\1border-top-left-radius:\\2;\\1border-top-".
"right-radius:\\3;\\1border-bottom-right-radius:\\4;\\1border-bottom-left-radius:\\5;", $this->css_data);
// start parsing css file
// find all class name
preg_match_all('/((@(media).+{.+{.+}\s+})|(((?!@(m|-)).)+{.+}))/Uis', $this->css_data, $css_arr);
// prepare regex
$regex = trim(trim(implode('|', array_map('preg_quote', $escaped))), '|');
//foreach the result array
foreach($css_arr[0] as $css_key=>$css_val) {
if(preg_match('/@(m|-)(.+){(.+})\s+}/Uis', $css_arr[0][$css_key], $media_arr)) {
$css_prefix = "@".$media_arr[1].$media_arr[2]." {\n";
$css_inner = '';
preg_match_all('/(.+){(.+)}/Uis', $media_arr[3], $css_rules);
foreach($css_rules[0] as $sub_key=>$sub_val) {
//ignore escaped classes
if(!$regex || ($regex && !preg_match('/('.$regex.')/i', $css_rules[1][$sub_key]))) {
if($rules = $this->parseCSSRules($css_rules[2][$sub_key])) {
$css_inner .= $css_rules[1][$sub_key]." {\n";
$css_inner .= " ".str_replace(";\n", ";\n ",trim($rules))."\n";
$css_inner .= " }\n";
}
}
}
$css_suffix = "}\n";
} else {
preg_match_all('/(.+){(.+)}/Uis', $css_arr[0][$css_key], $css_rules);
$css_prefix = '';
$css_inner = '';
foreach($css_rules[0] as $sub_key=>$sub_val) {
//ignore escaped classes
if(!$regex || ($regex && !preg_match('/('.$regex.')/i', $css_rules[1][$sub_key]))) {
if($rules = $this->parseCSSRules($css_rules[2][$sub_key])) {
$css_inner .= $css_rules[1][$sub_key]." {\n";
$css_inner .= " ".str_replace(";\n", ";\n ",trim($rules))."\n";
$css_inner .= "}\n";
}
}
}
$css_suffix = "";
}
if($css_inner) {
$this->css_flipped .= $css_prefix . $css_inner . $css_suffix;
$this->css_flipped = preg_replace('/({|})\n\n/Ui',"\\1\n", $this->css_flipped);
$this->css_flipped = preg_replace('/\s\s{/Ui'," {", $this->css_flipped);
$this->css_flipped = preg_replace('/(\v)\v+/',"\\1", $this->css_flipped);
}
}
return ($this->css_flipped);
}
/**
* Parse and flip the CSS data
*
* @param string
* @return string
*/
public function parseCSSRules($rules) {
$return = '';
$rules_arr = explode(";", $rules);
foreach($rules_arr as $rule) {
//ignore rules that doesn't need flipping
if(preg_match('/(left|right)/i', $rule)) {
//flip float
if(preg_match('/float\h*:\h*(.+)/i', $rule, $rule_arr)) {
$rule = 'float: '.((trim($rule_arr[1])=='left')?'right':'left');
$return .= trim($rule).";\n";
//flip text-align
} elseif(preg_match('/text-align\h*:\h*(.+)/i', $rule, $rule_arr)) {
$rule = 'text-align: '.((trim($rule_arr[1])=='left')?'right':'left');
$return .= trim($rule).";\n";
//flip padding, margin, border
} elseif(preg_match('/(\*|)(margin|padding|border)-(left|right)\h*:\h*(.+)/i', $rule, $rule_arr)) {
$dir = ((trim($rule_arr[3])=='left')?'right':'left');
//reset direction rule
if((trim($rule_arr[3]) == 'left' && !preg_match('/'.trim($rule_arr[2]).'\-right/i', $rules)) || (trim($rule_arr[2]) == 'right' && !preg_match('/'.trim($rule_arr[2]).'\-left/i', $rules))) {
$rule = trim($rule_arr[1]).trim($rule_arr[2]).'-'.$rule_arr[3].": 0;\n";
} else {
$rule = '';
}
$rule .= trim($rule_arr[1]).trim($rule_arr[2]).'-'.$dir.': '.$rule_arr[4];
$return .= trim($rule).";\n";
//flip border-radius
} elseif(preg_match('/border-(top|bottom)-(left|right)-radius\h*:\h*(.+)/i', $rule, $rule_arr)) {
$dir = ((trim($rule_arr[2])=='left')?'right':'left');
//reset direction rule
if((trim($rule_arr[2]) == 'left' && !preg_match('/'.trim($rule_arr[1]).'\-right/i', $rules)) || (trim($rule_arr[2]) == 'right' && !preg_match('/'.trim($rule_arr[1]).'\-left/i', $rules))) {
$rule = 'border-'.$rule_arr[1].'-'.$rule_arr[2].'-radius: 0;'."\n";
} else {
$rule = '';
}
//write new direction rule
$rule .= 'border-'.$rule_arr[1].'-'.$dir.'-radius: '.$rule_arr[3];
$return .= trim($rule).";\n";
//flip left, right
} elseif(preg_match('/\h*(left|right)\h*:\h*(.+)/i', $rule, $rule_arr)) {
$dir = ((trim($rule_arr[1])=='left')?'right':'left');
//reset LTR rule
if((trim($rule_arr[1]) == 'left' && !preg_match('/\h+right\h*:/i', $rules)) || (trim($rule_arr[1]) == 'right' && !preg_match('/\h+left\h*:/i', $rules))) {
$rule = trim($rule_arr[1]).": auto;\n";
} else {
$rule = '';
}
$rule .= $dir.': '.$rule_arr[2];
$return .= trim($rule).";\n";
}
}
}
return($return);
}
}
?>