forked from jednano/parse-css-font
-
Notifications
You must be signed in to change notification settings - Fork 1
/
parse.js
107 lines (81 loc) · 2.27 KB
/
parse.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'use strict'
var unquote = require('unquote')
var globalKeywords = require('css-global-keywords')
var systemFontKeywords = require('css-system-font-keywords')
var fontWeightKeywords = require('css-font-weight-keywords')
var fontStyleKeywords = require('css-font-style-keywords')
var fontStretchKeywords = require('css-font-stretch-keywords')
var splitBy = require('string-split-by')
var isSize = require('./lib/util').isSize
module.exports = parseFont
var cache = parseFont.cache = {}
function parseFont (value) {
if (typeof value !== 'string') throw new Error('Font argument must be a string.')
if (cache[value]) return cache[value]
if (value === '') {
throw new Error('Cannot parse an empty string.')
}
if (systemFontKeywords.indexOf(value) !== -1) {
return cache[value] = {system: value}
}
var font = {
style: 'normal',
variant: 'normal',
weight: 'normal',
stretch: 'normal',
lineHeight: 'normal',
size: '1rem',
family: ['serif']
}
var tokens = splitBy(value, /\s+/)
var token
while (token = tokens.shift()) {
if (globalKeywords.indexOf(token) !== -1) {
['style', 'variant', 'weight', 'stretch'].forEach(function(prop) {
font[prop] = token
})
return cache[value] = font
}
if (fontStyleKeywords.indexOf(token) !== -1) {
font.style = token
continue
}
if (token === 'normal' || token === 'small-caps') {
font.variant = token
continue
}
if (fontStretchKeywords.indexOf(token) !== -1) {
font.stretch = token
continue
}
if (fontWeightKeywords.indexOf(token) !== -1) {
font.weight = token
continue
}
if (isSize(token)) {
var parts = splitBy(token, '/')
font.size = parts[0]
if (parts[1] != null) {
font.lineHeight = parseLineHeight(parts[1])
}
else if (tokens[0] === '/') {
tokens.shift()
font.lineHeight = parseLineHeight(tokens.shift())
}
if (!tokens.length) {
throw new Error('Missing required font-family.')
}
font.family = splitBy(tokens.join(' '), /\s*,\s*/).map(unquote)
return cache[value] = font
}
throw new Error('Unknown or unsupported font token: ' + token)
}
throw new Error('Missing required font-size.')
}
function parseLineHeight(value) {
var parsed = parseFloat(value)
if (parsed.toString() === value) {
return parsed
}
return value
}