postcss-styl
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -210,3 +210,3 @@ "use strict" | ||
} | ||
const tokenizer = new Tokenizer(this.text, 0, this.text.length - 1) | ||
const tokenizer = new Tokenizer(this.text) | ||
const tokens = (this.tokens = []) | ||
@@ -213,0 +213,0 @@ const tokenIndexMap = (this.tokenIndexMap = {}) |
"use strict" | ||
const EOF = -1 | ||
const NULL = 0x00 | ||
const TAB = 0x09 | ||
const CR = 0x0d | ||
const LF = 0x0a | ||
const FF = 0x0c | ||
const SPACE = 0x20 | ||
const BANG = 0x21 // ! | ||
const DQUOTE = 0x22 // " | ||
const SQUOTE = 0x27 // ' | ||
const LPAREN = 0x28 // ( | ||
const RPAREN = 0x29 // ) | ||
const STAR = 0x2a // * | ||
const COMMA = 0x2c // , | ||
const DOT = 0x2e // . | ||
const SLASH = 0x2f // / | ||
const COLON = 0x3a // : | ||
const SEMI = 0x3b // ; | ||
const EQ = 0x3d // = | ||
const LBRACKET = 0x5b // [ | ||
const BACKSLASH = 0x5c // \ | ||
const RBRACKET = 0x5d // ] | ||
const LBRACE = 0x7b // { | ||
const RBRACE = 0x7d // } | ||
const PostcssTokenize = require("postcss/lib/tokenize") | ||
const Input = require("postcss/lib/input") | ||
/** | ||
* checks whether the given char is punctuator. | ||
* @param cc char | ||
* @returns `true` if the given char is punctuator | ||
*/ | ||
function isPunctuator(cc) { | ||
return ( | ||
cc === LPAREN || | ||
cc === LBRACE || | ||
cc === LBRACKET || | ||
cc === RPAREN || | ||
cc === RBRACE || | ||
cc === RBRACKET || | ||
cc === COMMA || | ||
cc === DOT || | ||
cc === SEMI || | ||
cc === COLON || | ||
cc === EQ || | ||
cc === BANG | ||
) | ||
} | ||
/** | ||
* checks whether the given char is quotes. | ||
* @param cc char | ||
* @returns `true` if the given char quotes | ||
*/ | ||
function isQuotes(cc) { | ||
return cc === DQUOTE || cc === SQUOTE | ||
} | ||
/** | ||
* Check whether the char code is a whitespace. | ||
* @param cc The char code to check. | ||
* @returns `true` if the char code is a whitespace. | ||
*/ | ||
function isWhitespace(cc) { | ||
return cc === TAB || cc === LF || cc === FF || cc === CR || cc === SPACE | ||
} | ||
/** | ||
* Tokenizer for Stylus. | ||
@@ -75,12 +13,30 @@ */ | ||
*/ | ||
constructor(text, start, end) { | ||
constructor(text) { | ||
this.text = text | ||
this.offset = start - 1 | ||
this.end = end | ||
this.state = "SCAN" | ||
this.nextTokenOffset = start | ||
this.lastCode = NULL | ||
this.nextTokenOffset = 0 | ||
const input = new Input(text) | ||
this.postcssTokenize = new PostcssTokenize(input, { | ||
ignoreErrors: true, | ||
}) | ||
} | ||
/** | ||
* Commit the current token. | ||
*/ | ||
commitToken(type, length) { | ||
const start = this.nextTokenOffset | ||
const offset = start + length | ||
const value = this.text.slice(start, offset) | ||
const token = { | ||
type, | ||
value, | ||
range: [start, offset], | ||
} | ||
this.nextTokenOffset = offset | ||
return token | ||
} | ||
/** | ||
* Get the tokens. | ||
@@ -92,276 +48,134 @@ * @returns The tokens | ||
let token = null | ||
while ((token = this.nextToken())) { | ||
yield token | ||
while ((token = this.postcssTokenize.nextToken())) { | ||
yield* this.processToken(token) | ||
} | ||
} | ||
/** | ||
* Get the next token. | ||
* @returns The next token or null. | ||
* @public | ||
*/ | ||
nextToken() { | ||
while (this.token == null) { | ||
const cc = this.scan() | ||
this.state = this[this.state](cc) || "SCAN" | ||
if (cc === EOF && !this.rescan) { | ||
break | ||
} | ||
} | ||
const { token } = this | ||
this.token = null | ||
return token | ||
*processToken(token) { | ||
const [type, text] = token | ||
yield* this[type](text) | ||
} | ||
/** | ||
* Scan the curr char code. | ||
* @returns The scan char code. | ||
* @private | ||
*/ | ||
scan() { | ||
if (this.rescan) { | ||
this.rescan = false | ||
return this.lastCode | ||
*processInlineComment() { | ||
const after = this.text.slice(this.nextTokenOffset) | ||
const index = after.search(/\r\n|\r|\n/u) | ||
let newText = null | ||
if (index > -1) { | ||
yield this.commitToken("inline-comment", index) | ||
newText = after.slice(index) | ||
} else { | ||
yield this.commitToken("inline-comment", after.length) | ||
newText = "" | ||
} | ||
return this.next() | ||
const input = new Input(newText) | ||
this.postcssTokenize = new PostcssTokenize(input, { | ||
ignoreErrors: true, | ||
}) | ||
} | ||
/** | ||
* Consume the next char code. | ||
* @returns The consumed char code. | ||
* @private | ||
*/ | ||
next() { | ||
if (this.offset <= this.end) { | ||
this.offset++ | ||
*word(text) { | ||
const { length } = text | ||
const rePunctuatorOrEscapeOrLineComment = /[\\(){}[\],.;:=!]|\/\//gu | ||
let r = null | ||
let start = 0 | ||
while ((r = rePunctuatorOrEscapeOrLineComment.exec(text))) { | ||
if (r[0] === "\\") { | ||
rePunctuatorOrEscapeOrLineComment.lastIndex++ | ||
continue | ||
} | ||
const wordLength = r.index - start | ||
if (wordLength > 0) { | ||
yield this.commitToken("word", wordLength) | ||
} | ||
if (r[0] === "//") { | ||
yield* this.processInlineComment() | ||
return | ||
} | ||
yield this.commitToken("punctuator", 1) | ||
start = rePunctuatorOrEscapeOrLineComment.lastIndex | ||
} | ||
if (this.offset > this.end) { | ||
return (this.lastCode = EOF) | ||
const wordLength = length - start | ||
if (wordLength > 0) { | ||
yield this.commitToken("word", wordLength) | ||
} | ||
return (this.lastCode = this.text.charCodeAt(this.offset)) | ||
} | ||
/** | ||
* Rescan the next state with the current code. | ||
*/ | ||
back() { | ||
this.rescan = true | ||
*"at-word"(text) { | ||
yield this.commitToken("word", text.length) | ||
} | ||
getText(indexOffset = 0) { | ||
const start = this.nextTokenOffset | ||
const offset = this.offset + indexOffset + 1 | ||
return this.text.slice(start, offset) | ||
*string(text) { | ||
yield this.commitToken("string", text.length) | ||
} | ||
/** | ||
* Commit the current token. | ||
*/ | ||
commitToken(type, indexOffset = 0) { | ||
const start = this.nextTokenOffset | ||
const offset = this.offset + indexOffset + 1 | ||
const value = this.text.slice(start, offset) | ||
this.token = { | ||
type, | ||
value, | ||
range: [start, offset], | ||
} | ||
this.nextTokenOffset = offset | ||
this.lastTokenType = type | ||
*comment(text) { | ||
yield this.commitToken("comment", text.length) | ||
} | ||
/** | ||
* @param cc The current char code. | ||
* @returns The next state. | ||
*/ | ||
SCAN(cc) { | ||
if (cc === CR) { | ||
return "CR" | ||
} | ||
if (cc === LF || cc === FF) { | ||
this.commitToken("linebreak") | ||
return "SCAN" | ||
} | ||
if (isWhitespace(cc)) { | ||
return "WHITESPACE" | ||
} | ||
if (cc === DQUOTE) { | ||
return "DQUOTE" | ||
} | ||
if (cc === SQUOTE) { | ||
return "SQUOTE" | ||
} | ||
if (cc === SLASH) { | ||
return "SLASH" | ||
} | ||
if (isPunctuator(cc)) { | ||
this.commitToken("punctuator") | ||
return "SCAN" | ||
} | ||
if (cc === EOF) { | ||
return "SCAN" | ||
} | ||
if (cc === BACKSLASH) { | ||
this.next() | ||
return "WORD" | ||
} | ||
return "WORD" | ||
} | ||
/* eslint-disable consistent-return, no-param-reassign */ | ||
WORD(cc) { | ||
while ( | ||
!isWhitespace(cc) && | ||
!isPunctuator(cc) && | ||
!isQuotes(cc) && | ||
cc !== EOF | ||
) { | ||
let next = this.next() | ||
if (cc === BACKSLASH) { | ||
next = this.next() | ||
} else if (cc === SLASH) { | ||
if (next === SLASH) { | ||
this.commitToken("word", -2) | ||
return "INLINE_COMMENT" | ||
} else if (next === STAR) { | ||
this.commitToken("word", -2) | ||
return "COMMENT" | ||
} | ||
*space(text) { | ||
const { length } = text | ||
const reLineBrakes = /\r\n|\r|\n/gu | ||
let r = null | ||
let start = 0 | ||
while ((r = reLineBrakes.exec(text))) { | ||
const spaceLength = r.index - start | ||
if (spaceLength > 0) { | ||
yield this.commitToken("whitespace", spaceLength) | ||
} | ||
cc = next | ||
yield this.commitToken( | ||
"linebreak", | ||
reLineBrakes.lastIndex - r.index | ||
) | ||
start = reLineBrakes.lastIndex | ||
} | ||
if (cc === LPAREN) { | ||
if (this.getText(-1) === "url") { | ||
this.commitToken("word", -1) | ||
return "URL" | ||
} | ||
const spaceLength = length - start | ||
if (spaceLength > 0) { | ||
yield this.commitToken("whitespace", spaceLength) | ||
} | ||
this.commitToken("word", -1) | ||
this.back() | ||
} | ||
CR(cc) { | ||
if (cc === LF) { | ||
this.commitToken("linebreak") | ||
} else { | ||
this.commitToken("linebreak", -1) | ||
this.back() | ||
} | ||
*brackets(text) { | ||
yield this.commitToken("punctuator", 1) | ||
yield this.commitToken("arguments", text.length - 2) | ||
yield this.commitToken("punctuator", 1) | ||
} | ||
WHITESPACE(cc) { | ||
while (isWhitespace(cc)) { | ||
if (cc === CR) { | ||
this.commitToken("whitespace", -1) | ||
return "CR" | ||
} | ||
if (cc === LF || cc === FF) { | ||
this.commitToken("whitespace", -1) | ||
this.back() | ||
return "SCAN" | ||
} | ||
cc = this.next() | ||
} | ||
this.commitToken("whitespace", -1) | ||
this.back() | ||
*":"() { | ||
yield* this.punctuator() | ||
} | ||
SLASH(cc) { | ||
if (cc === STAR) { | ||
return "COMMENT" | ||
} | ||
if (cc === SLASH) { | ||
return "INLINE_COMMENT" | ||
} | ||
this.commitToken("word", -1) | ||
this.back() | ||
*";"() { | ||
yield* this.punctuator() | ||
} | ||
COMMENT(cc) { | ||
while (cc !== EOF) { | ||
if (cc === STAR) { | ||
cc = this.next() | ||
if (cc === SLASH) { | ||
this.commitToken("comment") | ||
return | ||
} | ||
} | ||
cc = this.next() | ||
} | ||
this.commitToken("comment", -1) | ||
*"{"() { | ||
yield* this.punctuator() | ||
} | ||
INLINE_COMMENT(cc) { | ||
while (cc !== EOF) { | ||
if (cc === LF || cc === FF) { | ||
this.commitToken("inline-comment", -1) | ||
return this.back() | ||
} | ||
if (cc === CR) { | ||
this.commitToken("inline-comment", -1) | ||
return "CR" | ||
} | ||
cc = this.next() | ||
} | ||
this.commitToken("inline-comment", -1) | ||
*"}"() { | ||
yield* this.punctuator() | ||
} | ||
DQUOTE(cc) { | ||
this.skipString(cc, DQUOTE) | ||
*"("() { | ||
yield* this.punctuator() | ||
} | ||
SQUOTE(cc) { | ||
this.skipString(cc, SQUOTE) | ||
*")"() { | ||
yield* this.punctuator() | ||
} | ||
URL(cc) { | ||
if (isWhitespace(cc)) { | ||
return "URL" | ||
} | ||
if (cc === DQUOTE) { | ||
return "DQUOTE" | ||
} | ||
if (cc === SQUOTE) { | ||
return "SQUOTE" | ||
} | ||
this.skipArguments(cc) | ||
*"["() { | ||
yield* this.punctuator() | ||
} | ||
/** | ||
* Skip string | ||
*/ | ||
skipString(cc, end) { | ||
while (cc !== EOF) { | ||
if (cc === BACKSLASH) { | ||
cc = this.next() | ||
} else if (cc === end) { | ||
this.commitToken("string") | ||
return | ||
} | ||
cc = this.next() | ||
} | ||
this.commitToken("string", -1) | ||
*"]"() { | ||
yield* this.punctuator() | ||
} | ||
/** | ||
* Skip url arguments | ||
*/ | ||
skipArguments(cc) { | ||
while (cc !== EOF) { | ||
if (cc === BACKSLASH) { | ||
cc = this.next() | ||
} else if (cc === RPAREN) { | ||
this.commitToken("arguments") | ||
return | ||
} | ||
cc = this.next() | ||
} | ||
this.commitToken("arguments", -1) | ||
*punctuator() { | ||
yield this.commitToken("punctuator", 1) | ||
} | ||
/* eslint-enable consistent-return, no-param-reassign */ | ||
} |
{ | ||
"name": "postcss-styl", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "PostCSS parser plugin for converting Stylus syntax to PostCSS AST.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -23,7 +23,7 @@ # postcss-styl | ||
### Stylus to PostCSS AST | ||
### Lint [Stylus] with [stylelint] | ||
The main use of this plugin is to apply the [Stylus] syntax to linter using [PostCSS]. | ||
For example, if you want to use this plugin with [Stylelint], it is used as follows: | ||
For example, if you want to use this plugin with [stylelint], it is used as follows: | ||
@@ -30,0 +30,0 @@ 1. First, prepare a script that extends `postcss-syntax`. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
116073
3615