/*
* Copyright 2005, 2006, 2007 Florian Schmitz
*
* This file is part of CSSTidy.
*
* CSSTidy is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* CSSTidy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#include "csspp_globals.hpp"
using namespace std;
extern vector unit_values,color_values;
extern map replace_colors,all_properties;
string shorthand(string value)
{
string important = "";
if(is_important(value))
{
value = gvw_important(value);
important = "!important";
}
vector values = explode(" ",value);
switch(values.size())
{
case 4:
if(values[0] == values[1] && values[0] == values[2] && values[0] == values[3])
{
return values[0] + important;
}
else if(values[1] == values[3] && values[0] == values[2])
{
return values[0] + " " + values[1] + important;
}
else if(values[1] == values[3])
{
return values[0] + " " + values[1] + " " + values[2] + important;
}
else return value + important;
break;
case 3:
if(values[0] == values[1] && values[0] == values[2])
{
return values[0] + important;
}
else if(values[0] == values[2])
{
return values[0] + " " + values[1] + important;
}
else return value + important;
break;
case 2:
if(values[0] == values[1])
{
return values[0] + important;
}
else return value + important;
break;
default:
return value + important;
}
}
string compress_numbers(string subvalue, string property, string function)
{
string units[] = {"in", "cm", "mm", "pt", "pc", "px", "rem", "%", "ex", "gd", "em", "vw", "vh",
"vm", "ch", "deg", "grad", "rad", "turn", "ms", "s", "khz", "hz" }; // sync for loop
vector temp;
if(property == "font")
{
temp = explode("/",subvalue);
}
else
{
temp.push_back(subvalue);
}
for (int i = 0; i < temp.size(); ++i)
{
if(!(temp[i].length() > 0 && (ctype_digit(temp[i][0])) ||
temp[i].length() > 1 && (ctype_digit(temp[i][1])) && (temp[i][0] == '+' || temp[i][0] == '-' )))
{
// As temp[i] does not begin with a digit
// (optionally preceded by a plus or minus sign), make no changes to it.
continue;
}
if(function == "" && in_str_array(color_values,property))
{
temp[i] = "#" + temp[i];
//csstidy::log("Inserting missing '#'", Warning); // FIXME: Make log() a static method
}
if(str2f(temp[i]) == 0)
{
temp[i] = "0";
}
else
{
bool unit_found = false;
temp[i] = strtolower(temp[i]);
for(int j = 0; j < 21; ++j )
{
if(temp[i].find(units[j]) != string::npos)
{
temp[i] = f2str(str2f(temp[i])) + units[j];
unit_found = true;
break;
}
}
if(function == "" && !unit_found && in_str_array(unit_values,property))
{
temp[i] = f2str(str2f(temp[i]));
temp[i] += "px";
//csstidy::log("Unit required, inserting 'px'", Warning); // FIXME: Make log() a static method
}
else if(!unit_found)
{
temp[i] = f2str(str2f(temp[i]));
}
// Remove leading zero
if (abs( (int) str2f(temp[i])) < 1) {
if (str2f(temp[i]) < 0) {
temp[i] = '-' + temp[i].substr(2);
} else {
temp[i] = temp[i].substr(1);
}
}
}
}
return (temp.size() > 1) ? temp[0] + "/" + temp[1] : ((temp.size() > 0) ? temp[0] : "");
}
bool property_is_next(string istring, int pos)
{
istring = istring.substr(pos,istring.length()-pos);
pos = istring.find_first_of(':',0);
if(pos == string::npos)
{
return false;
}
istring = strtolower(trim(istring.substr(0,pos)));
return (all_properties.count(istring) > 0);
}
string cut_color(string color)
{
if(strtolower(color.substr(0,4)) == "rgb(")
{
vector color_tmp = explode(",",color.substr(4,color.length()-5));
for (int i = 0; i < color_tmp.size(); ++i)
{
color_tmp[i] = trim(color_tmp[i]);
if(color_tmp[i].at(color_tmp[i].length()-1) == '%')
{
color_tmp[i] = f2str(round(255 * atoi(color_tmp[i].c_str())/100,0));
}
if(atoi(color_tmp[i].c_str()) > 255) color_tmp[i] = 255;
}
color = "#";
for (int i = 0; i < color_tmp.size(); ++i)
{
if(atoi(color_tmp[i].c_str()) < 16)
{
color += "0" + dechex(atoi(color_tmp[i].c_str()));
}
else
{
color += dechex(atoi(color_tmp[i].c_str()));
}
}
}
// Fix bad color names
if(replace_colors.count(strtolower(color)) > 0)
{
color = replace_colors[strtolower(color)];
}
if(color.length() == 7)
{
string color_temp = strtoupper(color);
if(color_temp[0] == '#' && color_temp[1] == color_temp[2] && color_temp[3] == color_temp[4] && color_temp[5] == color_temp[6])
{
color = "#";
color += color_temp[2];
color += color_temp[3];
color += color_temp[5];
}
}
string temp = strtolower(color);
/* color name -> hex code */
if(temp == "black") return "#000";
if(temp == "fuchsia") return "#f0f";
if(temp == "white") return "#fff";
if(temp == "yellow") return "#ff0";
/* hex code -> color name */
if(temp == "#800000") return "maroon";
if(temp == "#ffa500") return "orange";
if(temp == "#808000") return "olive";
if(temp == "#800080") return "purple";
if(temp == "#008000") return "green";
if(temp == "#000080") return "navy";
if(temp == "#008080") return "teal";
if(temp == "#c0c0c0") return "silver";
if(temp == "#808080") return "gray";
if(temp == "#f00") return "red";
return color;
}
int c_font_weight(string& value)
{
string important = "";
if(is_important(value))
{
important = "!important";
value = gvw_important(value);
}
if(value == "bold")
{
value = "700"+important;
return 700;
}
else if(value == "normal")
{
value = "400"+important;
return 400;
}
return 0;
}
void merge_selectors(sstore& input)
{
for(sstore::iterator i = input.begin(), e = input.end(); i != e;)
{
string newsel = "";
// Check if properties also exist in another selector
vector keys;
for(sstore::iterator j = input.begin(); j != input.end(); j++ )
{
if(j->first == i->first)
{
continue;
}
if(input[j->first] == input[i->first])
{
keys.push_back(j->first);
}
}
if(keys.size() > 0)
{
newsel = i->first;
for(int k = 0; k < keys.size(); ++k)
{
input.erase(keys[k]);
newsel += "," + keys[k];
}
input[newsel] = i->second;
input.erase(i);
e = input.end();
} else {
i++;
}
}
}