canonical
Version:
Canonical code style linter and formatter for JavaScript, SCSS, CSS and JSON.
1 lines • 3.51 kB
JavaScript
;module.exports = function(css){var TokenType=require('../token-types');var tokens=[], urlMode=false, blockMode=0, c, cn, pos=0, tn=0, ln=1, col=1;var Punctuation={' ':TokenType.Space, '\n':TokenType.Newline, '\r':TokenType.Newline, '\t':TokenType.Tab, '!':TokenType.ExclamationMark, '"':TokenType.QuotationMark, '#':TokenType.NumberSign, '$':TokenType.DollarSign, '%':TokenType.PercentSign, '&':TokenType.Ampersand, '\'':TokenType.Apostrophe, '(':TokenType.LeftParenthesis, ')':TokenType.RightParenthesis, '*':TokenType.Asterisk, '+':TokenType.PlusSign, ',':TokenType.Comma, '-':TokenType.HyphenMinus, '.':TokenType.FullStop, '/':TokenType.Solidus, ':':TokenType.Colon, ';':TokenType.Semicolon, '<':TokenType.LessThanSign, '=':TokenType.EqualsSign, '>':TokenType.GreaterThanSign, '?':TokenType.QuestionMark, '@':TokenType.CommercialAt, '[':TokenType.LeftSquareBracket, ']':TokenType.RightSquareBracket, '^':TokenType.CircumflexAccent, '_':TokenType.LowLine, '{':TokenType.LeftCurlyBracket, '|':TokenType.VerticalLine, '}':TokenType.RightCurlyBracket, '~':TokenType.Tilde};function pushToken(type, value, column){tokens.push({tn:tn++, ln:ln, col:column, type:type, value:value});}function isDecimalDigit(c){return '0123456789'.indexOf(c) >= 0;}function parseSpaces(css){var start=pos;for(; pos < css.length; pos++) {if(css.charAt(pos) !== ' ')break;}pushToken(TokenType.Space, css.substring(start, pos--), col);col += pos - start;}function parseString(css, q){var start=pos;for(pos++; pos < css.length; pos++) {if(css.charAt(pos) === '\\')pos++;else if(css.charAt(pos) === q)break;}pushToken(q === '"'?TokenType.StringDQ:TokenType.StringSQ, css.substring(start, pos + 1), col);col += pos - start;}function parseDecimalNumber(css){var start=pos;for(; pos < css.length; pos++) {if(!isDecimalDigit(css.charAt(pos)))break;}pushToken(TokenType.DecimalNumber, css.substring(start, pos--), col);col += pos - start;}function parseIdentifier(css){var start=pos;while(css.charAt(pos) === '/') pos++;for(; pos < css.length; pos++) {if(css.charAt(pos) === '\\')pos++;else if(css.charAt(pos) in Punctuation)break;}var ident=css.substring(start, pos--);urlMode = urlMode || ident === 'url';pushToken(TokenType.Identifier, ident, col);col += pos - start;}function parseMLComment(css){var start=pos;for(pos = pos + 2; pos < css.length; pos++) {if(css.charAt(pos) === '*' && css.charAt(pos + 1) === '/'){pos++;break;}}var comment=css.substring(start, pos + 1);pushToken(TokenType.CommentML, comment, col);var newlines=comment.split('\n');if(newlines.length > 1){ln += newlines.length - 1;col = newlines[newlines.length - 1].length;}else {col += pos - start;}}function parseSLComment(css){var start=pos;for(pos += 2; pos < css.length; pos++) {if(css.charAt(pos) === '\n' || css.charAt(pos) === '\r'){break;}}pushToken(TokenType.CommentSL, css.substring(start, pos--), col);col += pos - start;}function getTokens(css){for(pos = 0; pos < css.length; col++, pos++) {c = css.charAt(pos);cn = css.charAt(pos + 1);if(c === '/' && cn === '*'){parseMLComment(css);}else if(!urlMode && c === '/' && cn === '/'){parseSLComment(css);}else if(c === '"' || c === '\''){parseString(css, c);}else if(c === ' '){parseSpaces(css);}else if(c in Punctuation){pushToken(Punctuation[c], c, col);if(c === '\n' || c === '\r'){ln++;col = 0;}if(c === ')')urlMode = false;if(c === '{')blockMode++;if(c === '}')blockMode--;}else if(isDecimalDigit(c)){parseDecimalNumber(css);}else {parseIdentifier(css);}}return tokens;}return getTokens(css);};