给出一个字体CSS字符串,如:
font:italic bold 12px/30px Georgia, serif;
或
font:12px verdana;
我想将其转换为长手形式,即:
font-style: italic; font-weight: bold;
这是我悲惨的尝试:http://pastebin.com/e3KdMvGT
但当然它不适用于第二个例子,因为它期望事情有序,我该如何改进呢?
答案 0 :(得分:5)
这是一个应该完成工作的功能。问题在于font-style,font-variant和font-weight属性以及值“normal”,您可以在css specs([[ <'font-style'> || <'font-variant'> || <'font-weight'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
)中阅读。
$testStrings = array('12px/14px sans-serif',
'80% sans-serif',
'x-large/110% "New Century Schoolbook", serif',
'x-large/110% "New Century Schoolbook"',
'bold italic large Palatino, serif ',
'normal small-caps 120%/120% fantasy',
'italic bold 12px/30px Georgia, serif',
'12px verdana');
foreach($testStrings as $font){
echo "Test ($font)\n<pre>
";
$details = extractFull($font);
print_r($details);
echo "
</pre>";
}
function extractFull($fontString){
// Split $fontString. The only area where quotes should be found is around font-families. Which are at the end.
$parts = preg_split('`("|\')`', $fontString, 2, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
$chunks = preg_split('` `', $parts[0], NULL, PREG_SPLIT_NO_EMPTY);
if(isset($parts[1])){
$chunks[] = $parts[1] . $parts[2];
}
$details = array();
$next = -1;
// Manage font-style / font-variant / font-weight properties
$possibilities = array();
$fontStyle = array('italic', 'oblique');
$fontVariant = array('small-caps');
$fontWeight = array('bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900');
// First pass on chunks 0 to 2 to see what each can be
for($i = 0; $i < 3; $i++){
$possibilities[$i] = array();
if(!isset($chunks[$i])){
if($next == -1){
$next = $i;
}
continue;
}
if(in_array($chunks[$i], $fontStyle)){
$possibilities[$i] = 'font-style';
}
else if(in_array($chunks[$i], $fontVariant)){
$possibilities[$i] = 'font-variant';
}
else if(in_array($chunks[$i], $fontWeight)){
$possibilities[$i] = 'font-weight';
}
else if($chunks[$i] == 'normal'){
$possibilities['normal'] = 1;
}
else if($next == -1){
// Used to know where other properties will start at
$next = $i;
}
}
// Second pass to determine what real properties are defined
for($i = 0; $i < 3; $i++){
if(!empty($possibilities[$i])){
$details[$possibilities[$i]] = $chunks[$i];
}
}
// Third pass to set the properties which have to be set as "normal"
if(!empty($possibilities['normal'])){
$properties = array('font-style', 'font-variant', 'font-weight');
foreach($properties as $property){
if(!isset($details[$property])){
$details[$property] = 'normal';
}
}
}
if(!isset($chunks[$next])){
return $details;
}
// Extract font-size and line height
if(strpos($chunks[$next], '/')){
$size = explode('/', $chunks[$next]);
$details['font-size'] = $size[0];
$details['line-height'] = $size[1];
$details['font-family'] = $chunks[$next+1];
}
else if(preg_match('`^-?[0-9]+`', $chunks[$next]) ||
in_array($chunks[$next], array('xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'larger', 'smaller'))){
$details['font-size'] = $chunks[$next];
$details['font-family'] = $chunks[$next+1];
}
else{
$details['font-family'] = $chunks[$next];
}
return $details;
}
答案 1 :(得分:2)
这是我的尝试
function rewriteFont($short) {
$short = str_replace("font:","",$short);
$values = explode(" ", $short);
$length = count($values);
$familyLength = 0;
for($i = 0; $i < $length; $i++) {
$currentValue = $values[$i];
if($currentValue == 'italic' || $currentValue == 'oblique' ) {
echo "font-style:{$currentValue};";
}
else if($currentValue == 'small-caps') {
echo "font-variant:{$currentValue};";
}
else if ($currentValue == 'bold' || $currentValue == 'bolder' || $currentValue == 'lighter' || is_numeric($currentValue) ) {
echo "font-weight:{$currentValue};";
}
else if (strpos($currentValue, "px") || strpos($currentValue, "em") || strpos($currentValue, "ex")|| strpos($currentValue, "pt")
|| strpos($currentValue, "%") || $currentValue == "xx-small" || $currentValue == "x-small" || $currentValue == "small"
|| $currentValue == "medium" || $currentValue == "large" || $currentValue == "x-large" || $currentValue == "xx-large") {
$sizeLineHeight = explode("/", $currentValue);
echo "font-size:{$sizeLineHeight[0]};";
if(isset($sizeLineHeight[1])) {
echo "line-height:{$sizeLineHeight[1]};";
}
}
else {
if($familyLength == 0) {
echo "font-family:{$currentValue} ";
}
else {
echo $currentValue;
}
$familyLength++;
}
}
}
答案 2 :(得分:2)
遵循规范,我会做以下代码。它适用于规范中的所有示例。你可以在这里看到它:http://codepad.viper-7.com/ABhc22
function font($s){
$fontStyle = array('normal', 'italic', 'oblique', 'inherit');
$fontVariant = array('normal', 'small-caps','inherit');
$fontSize = array('xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large');
$fontWeight = array('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'inherit');
$s = str_replace('font: ', '', $s);
$array = explode(' ', $s);
$count = count($array);
$sizeFound = false;
$final = array();
$final['font-style'] = 'normal';
$final['font-variant'] = 'normal';
$final['font-weight'] = 'normal';
for($i = 0; $i < $count; $i++){
$cur = $array[$i];
if($sizeFound){
$final['font-family'] = isset($final['font-family']) ? $final['font-family'].$cur : $cur;
}else if(strripos($cur,'%') !== false || strripos($cur,'px') !== false || in_array($cur, $fontSize)){
$sizeFound = true;
$size = explode('/', $cur);
if(count($size) > 1){
$final['font-size'] = $size[0];
$final['line-height'] = $size[1];
}else
$final['font-size'] = $size[0];
}else{
if(in_array($cur, $fontStyle))
$final['font-style'] = $cur;
if(in_array($cur, $fontVariant))
$final['font-variant'] = $cur;
if(in_array($cur, $fontWeight))
$final['font-weight'] = $cur;
}
}
$ret = '';
foreach($final as $prop => $val)
$ret .= $prop.': '.$val.';';
return $ret;
}
我猜它可以优化。 :)
答案 3 :(得分:0)
您可以查看CSSTidy,其代码是开源的,并尝试对其进行反向工程。