5

Basically, I want this:

h2 {
    font: bold 36px/2em "Times New Roman"
}

To this:

h2 {
    font-size: 36px;
    font-weight: bold;
    line-height: 2em;
    font-family: "Times New Roman"
}

And other variations, of course. Does anyone know of a function that does this so I don't have to code it myself? :)

3
  • 2
    I'd like to have a function that does the inverse.. Commented May 18, 2010 at 7:04
  • 1
    @Alix Axel: Yup that is better choice and more logical :) Commented May 18, 2010 at 7:06
  • Yes, I would like it to manage both ways, of course :) Commented May 18, 2010 at 7:42

2 Answers 2

3

Based on this CSS Shorthand for the Font Element:

CSS Font Shorthand Style Guide

I've come up with the following regular expression:

font:(?:\s+(inherit|normal|italic|oblique))?(?:\s+(inherit|normal|small-caps))?(?:\s+(inherit|normal|bold(?:er)?|lighter|[1-9]00))?(?:\s+(\d+(?:%|px|em|pt)?|(?:x(?:x)?-)?(?:small|large)r?)|medium|inherit)(?:\/(\d+(?:%|px|em|pt)?|normal|inherit))?(?:\s+(inherit|default|.+?));?$

Obtained from these smaller regular expressions:

$font['style'] = '(?:\s+(inherit|normal|italic|oblique))?';
$font['variant'] = '(?:\s+(inherit|normal|small-caps))?';
$font['weight'] = '(?:\s+(inherit|normal|bold(?:er)?|lighter|[1-9]00))?';
$font['size'] = '(?:\s+(\d+(?:%|px|em|pt)?|(?:x(?:x)?-)?(?:small|large)r?)|medium|inherit)';
$font['height'] = '(?:\/(\d+(?:%|px|em|pt)?|normal|inherit))?';
$font['family'] = '(?:\s+(inherit|default|.+?))';

Usage:

$regex = 'font:' . implode('', $font) . ';?$';    
$matches = array();
$shorthand = 'font: bold 36px/2em Arial, Verdana, "Times New Roman";';

if (preg_match('~' . $regex . '~i', $shorthand, $matches) > 0)
{
    echo '<pre>';    
    if (strlen($matches[1]) > 0) { // font-style is optional
        print_r('font-style: ' . $matches[1] . ';' . "\n");
    }

    if (strlen($matches[2]) > 0) { // font-variant is optional
        print_r('font-variant: ' . $matches[2] . ';' . "\n");
    }

    if (strlen($matches[3]) > 0) { // font-weight is optional
        print_r('font-weight: ' . $matches[3] . ';' . "\n");
    }

    print_r('font-size: ' . $matches[4] . ';' . "\n"); // required

    if (strlen($matches[5]) > 0) { // line-height is optional
        print_r('line-height: ' . $matches[5] . ';' . "\n");
    }

    print_r('font-family: ' . $matches[6] . ';' . "\n"); // required
    echo '</pre>';

    echo '<pre>';
    print_r($matches);
    echo '</pre>';
}

Output:

font-weight: bold;
font-size: 36px;
line-height: 2em;
font-family: Arial, Verdana, "Times New Roman";

Array
(
    [0] => font: bold 36px/2em Arial, Verdana, "Times New Roman";
    [1] => 
    [2] => 
    [3] => bold
    [4] => 36px
    [5] => 2em
    [6] => Arial, Verdana, "Times New Roman"
)

This is meant for extraction not validation since it accepts stuff like xx-smaller (which isn't valid).

To make the expanded version you can either use preg_match() or preg_replace(), although using the latter would be more difficult to "ignore" unused declarations.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I'll look further into this!
0

There is no such function in PHP. You could create such a function - I would start with a map that contains [styleRuleName => [{sets of valid attributes}]] for each shorthand selector you wish to expand. I think you'll find this to be a bit of a nightmare to code though.

2 Comments

Of course there is no built in function, I meant a third-party function. I could obviously code it myself, but I don't want to :)
Not aware of such a third party function either. Most people are concerned with combining attributes, not expanding them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.