Skip to content

Commit

Permalink
Merge pull request #7 from papandreou/feature/css-fonts-module-level-4
Browse files Browse the repository at this point in the history
Add support for CSS Fonts Module level 4 features
  • Loading branch information
Bram Stein authored Feb 17, 2020
2 parents f76f0c4 + 9d2b244 commit bb493db
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 11 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock = false
39 changes: 29 additions & 10 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
VARIATION: 1,
LINE_HEIGHT: 2,
FONT_FAMILY: 3,
BEFORE_FONT_FAMILY: 4
BEFORE_FONT_FAMILY: 4,
AFTER_OBLIQUE: 5
};

/**
Expand All @@ -36,8 +37,8 @@
var identifiers = str.replace(/^\s+|\s+$/, '').replace(/\s+/g, ' ').split(' ');

for (var i = 0; i < identifiers.length; i += 1) {
if (/^(-?\d|--)/.test(identifiers[i]) ||
!/^([_a-zA-Z0-9-]|[^\0-\237]|(\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?|\\[^\n\r\f0-9a-f]))+$/.test(identifiers[i])) {
if (/^(?:-?\d|--)/.test(identifiers[i]) ||
!/^(?:[_a-zA-Z0-9-]|[^\0-\237]|(?:\\[0-9a-f]{1,6}(?:\r\n|[ \n\r\t\f])?|\\[^\n\r\f0-9a-f]))+$/.test(identifiers[i])) {
return null;
}
}
Expand Down Expand Up @@ -83,24 +84,42 @@
result['font-family'].push(identifier);
}
buffer = '';
} else if (state === states.AFTER_OBLIQUE && c === ' ') {
if (/^(?:\+|-)?(?:[0-9]*\.)?[0-9]+(?:deg|grad|rad|turn)$/.test(buffer)) {
result['font-style'] += ' ' + buffer;
buffer = '';
} else {
// The 'oblique' token was not followed by an angle.
// Backtrack to allow the token to be parsed as VARIATION
i -= 1;
}
state = states.VARIATION;
} else if (state === states.VARIATION && (c === ' ' || c === '/')) {
if (/^((xx|x)-large|(xx|s)-small|small|large|medium)$/.test(buffer) ||
/^(larg|small)er$/.test(buffer) ||
/^(\+|-)?([0-9]*\.)?[0-9]+(em|ex|ch|rem|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)$/.test(buffer)) {
if (/^(?:(?:xx|x)-large|(?:xx|s)-small|small|large|medium)$/.test(buffer) ||
/^(?:larg|small)er$/.test(buffer) ||
/^(?:\+|-)?(?:[0-9]*\.)?[0-9]+(?:em|ex|ch|rem|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)$/.test(buffer)) {
state = c === '/' ? states.LINE_HEIGHT : states.BEFORE_FONT_FAMILY;
result['font-size'] = buffer;
} else if (/^(italic|oblique)$/.test(buffer)) {
} else if (/^italic$/.test(buffer)) {
result['font-style'] = buffer;
} else if (/^oblique$/.test(buffer)) {
result['font-style'] = buffer;
state = states.AFTER_OBLIQUE;
} else if (/^small-caps$/.test(buffer)) {
result['font-variant'] = buffer;
} else if (/^(bold(er)?|lighter|[1-9]00)$/.test(buffer)) {
} else if (/^(?:bold(?:er)?|lighter)$/.test(buffer)) {
result['font-weight'] = buffer;
} else if (/^((ultra|extra|semi)-)?(condensed|expanded)$/.test(buffer)) {
} else if (/^[+-]?(?:[0-9]*\.)?[0-9]+(?:e[+-]?(?:0|[1-9][0-9]*))?$/.test(buffer)) {
var num = parseFloat(buffer);
if (num >= 1 && num <= 1000) {
result['font-weight'] = buffer;
}
} else if (/^(?:(?:ultra|extra|semi)-)?(?:condensed|expanded)$/.test(buffer)) {
result['font-stretch'] = buffer;
}
buffer = '';
} else if (state === states.LINE_HEIGHT && c === ' ') {
if (/^(\+|-)?([0-9]*\.)?[0-9]+(em|ex|ch|rem|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)?$/.test(buffer)) {
if (/^(?:\+|-)?([0-9]*\.)?[0-9]+(?:em|ex|ch|rem|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)?$/.test(buffer)) {
result['line-height'] = buffer;
}
state = states.BEFORE_FONT_FAMILY;
Expand Down
23 changes: 22 additions & 1 deletion test/parser-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ describe('CSS Font parser', function () {
it('correctly parses font-style', function () {
expect(parse('italic 12px serif')).to.eql({ 'font-size': '12px', 'font-style': 'italic', 'font-family': ['serif'] });
expect(parse('oblique 12px serif')).to.eql({ 'font-size': '12px', 'font-style': 'oblique', 'font-family': ['serif'] });
expect(parse('oblique 20deg 12px serif')).to.eql({ 'font-size': '12px', 'font-style': 'oblique 20deg', 'font-family': ['serif'] });
expect(parse('oblique 0.02turn 12px serif')).to.eql({ 'font-size': '12px', 'font-style': 'oblique 0.02turn', 'font-family': ['serif'] });
expect(parse('oblique .04rad 12px serif')).to.eql({ 'font-size': '12px', 'font-style': 'oblique .04rad', 'font-family': ['serif'] });
});

it('correctly parses font-variant', function () {
Expand All @@ -142,9 +145,27 @@ describe('CSS Font parser', function () {
expect(parse('bolder 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': 'bolder', 'font-family': ['serif'] });
expect(parse('lighter 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': 'lighter', 'font-family': ['serif'] });

for (var i = 1; i < 10; i += 1) {
for (var i = 1; i <= 10; i += 1) {
expect(parse(i * 100 + ' 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': i * 100, 'font-family': ['serif'] });
}

expect(parse('1 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '1', 'font-family': ['serif'] });
expect(parse('723 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '723', 'font-family': ['serif'] });
expect(parse('1000 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '1000', 'font-family': ['serif'] });
expect(parse('1000.00 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '1000.00', 'font-family': ['serif'] });
expect(parse('1e3 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '1e3', 'font-family': ['serif'] });
expect(parse('1e+1 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '1e+1', 'font-family': ['serif'] });
expect(parse('200e-2 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '200e-2', 'font-family': ['serif'] });
expect(parse('123.456 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '123.456', 'font-family': ['serif'] });
expect(parse('+123 12px serif')).to.eql({ 'font-size': '12px', 'font-weight': '+123', 'font-family': ['serif'] });

expect(parse('0 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
expect(parse('-1 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
expect(parse('1000. 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
expect(parse('1000.1 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
expect(parse('1001 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
expect(parse('1.1e3 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
expect(parse('1e-2 12px serif')).to.eql({ 'font-size': '12px', 'font-family': ['serif'] });
});

it('correctly parses font-stretch', function () {
Expand Down

0 comments on commit bb493db

Please sign in to comment.