将CSS字体简写转换为长手

Abs*_*Abs 3 css php

给定一个字体CSS字符串,例如:

font:italic bold 12px/30px Georgia, serif;
Run Code Online (Sandbox Code Playgroud)

要么

font:12px verdana;
Run Code Online (Sandbox Code Playgroud)

我想将其转换为长手形式,即:

font-style: italic; font-weight: bold;

这是我悲惨的尝试:http://pastebin.com/e3KdMvGT

但是当然它不适用于第二个例子,因为它期望事情有序,我该如何改进呢?

Ark*_*rkh 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;
}
Run Code Online (Sandbox Code Playgroud)