@emmetio/abbreviation
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -461,10 +461,9 @@ 'use strict'; | ||
var consumeRepeat = function(stream) { | ||
if (stream.next() !== '*') { | ||
stream.backUp(1); | ||
throw stream.error('Expected * character for repeater'); | ||
if (stream.eat('*')) { | ||
const value = stream.consume(/[0-9]/); | ||
// XXX think about extending repeat syntax with through numbering | ||
return {count: value ? +value : null}; | ||
} | ||
const value = stream.consume(/[0-9]/); | ||
// XXX think about extending repeat syntax with through numbering | ||
return {count: value ? +value : null}; | ||
return null; | ||
}; | ||
@@ -476,11 +475,11 @@ | ||
* @param {StringStream} stream | ||
* @return {String} | ||
* @return {String} Returns `null` if unable to consume quoted value from current | ||
* position | ||
*/ | ||
var consumeQuoted = function(stream) { | ||
const quote = stream.next(); | ||
if (!isQuote(quote)) { | ||
stream.backUp(1); | ||
throw stream.error('Expected single or double quote for string literal'); | ||
if (!isQuote(stream.peek())) { | ||
return null; | ||
} | ||
const quote = stream.next(); | ||
const start = stream.pos; | ||
@@ -497,16 +496,15 @@ if (!stream.skipQuoted(quote)) { | ||
* @param {StringStream} stream [description] | ||
* @return {String} | ||
* @return {String} Returns `null` if unable to consume text node from current | ||
* position | ||
*/ | ||
var consumeTextNode = function(stream) { | ||
if (stream.next() !== '{') { | ||
stream.backUp(1); | ||
throw stream.error('Expected { as a beginning of text node'); | ||
if (stream.peek() !== '{') { | ||
return null; | ||
} | ||
const start = stream.pos; | ||
let stack = 1; | ||
const start = stream.pos + 1; | ||
let stack = 0; | ||
while (!stream.eol()) { | ||
if (isQuote(stream.peek())) { | ||
consumeQuoted(stream); | ||
if (consumeQuoted(stream) !== null) { | ||
continue; | ||
@@ -545,4 +543,4 @@ } | ||
var consumeAttributes = function(stream) { | ||
if (stream.next() !== '[') { | ||
throw stream.error('Expected "[" brace'); | ||
if (!stream.eat('[')) { | ||
return null; | ||
} | ||
@@ -553,13 +551,12 @@ | ||
while (!stream.eol()) { | ||
stream.consume(reSpaceChar); | ||
const next = stream.peek(); | ||
stream.eatWhile(reSpaceChar); | ||
if (next === ']') { // end of attribute set | ||
stream.next(); | ||
if (stream.eat(']')) { // end of attribute set | ||
return result; | ||
} | ||
if (isQuote(next)) { | ||
let next = consumeQuoted(stream); | ||
if (next !== null) { | ||
// Found quoted default value | ||
result.push({name: null, value: consumeQuoted(stream)}); | ||
result.push({name: null, value: next}); | ||
continue; | ||
@@ -569,18 +566,17 @@ } | ||
// Consume next word: could be either attribute name or unquoted default value | ||
const nextWord = stream.consume(reUnquotedValueChar); | ||
if (!nextWord) { | ||
if (next = stream.consume(reUnquotedValueChar)) { | ||
if (!reAttributeName.test(next)) { | ||
result.push({name: null, value: next}); | ||
continue; | ||
} | ||
} else { | ||
throw stream.error('Expected attribute name or default value'); | ||
} | ||
if (!reAttributeName.test(nextWord)) { | ||
result.push({name: null, value: nextWord}); | ||
continue; | ||
} | ||
const attr = {name: nextWord}; | ||
const attr = {name: next}; | ||
result.push(attr); | ||
// Check for last character: if it’s a `.`, user wants boolean attribute | ||
if (nextWord[nextWord.length - 1] === '.') { | ||
attr.name = nextWord.slice(0, nextWord.length - 1); | ||
if (next[next.length - 1] === '.') { | ||
attr.name = next.slice(0, next.length - 1); | ||
attr.options = {boolean: true}; | ||
@@ -592,13 +588,7 @@ continue; | ||
// or React-like expression | ||
if (stream.peek() === '=') { | ||
stream.next(); | ||
const next = stream.peek(); | ||
if (isQuote(next)) { | ||
attr.value = consumeQuoted(stream); | ||
continue; | ||
} | ||
if (next === '{') { | ||
attr.value = consumeTextNode(stream); | ||
if (stream.eat('=')) { | ||
if ((next = consumeQuoted(stream)) !== null) { | ||
attr.value = next; | ||
} else if ((next = consumeTextNode(stream)) !== null) { | ||
attr.value = next; | ||
attr.options = { | ||
@@ -608,6 +598,5 @@ before: '{', | ||
}; | ||
continue; | ||
} else { | ||
attr.value = stream.consume(reUnquotedValueChar); | ||
} | ||
attr.value = stream.consume(reUnquotedValueChar); | ||
} | ||
@@ -628,33 +617,29 @@ } | ||
var consumeElement = function(stream) { | ||
const node = new Node(); | ||
// consume element name, if provided | ||
const start = stream.pos; | ||
const node = new Node(stream.consume(reNameChar)); | ||
while (!stream.eol()) { | ||
const ch = stream.peek(); | ||
let next; | ||
if (ch === '.') { | ||
stream.next(); | ||
if (stream.eat('.')) { | ||
node.addClass(stream.consume(reWordChar)); | ||
} else if (ch === '#') { | ||
stream.next(); | ||
} else if (stream.eat('#')) { | ||
node.setAttribute('id', stream.consume(reWordChar)); | ||
} else if (ch === '[') { | ||
const attrs = consumeAttributes(stream); | ||
for (let i = 0, il = attrs.length; i < il; i++) { | ||
node.setAttribute(attrs[i]); | ||
} | ||
} else if (ch === '{') { | ||
node.value = consumeTextNode(stream); | ||
} else if (reNameChar.test(ch) && stream.pos === start) { | ||
node.name = stream.consume(reNameChar); | ||
} else if (ch === '*') { | ||
node.repeat = consumeRepeat(stream); | ||
} else if (ch === '/') { | ||
} else if (stream.eat('/')) { | ||
// A self-closing indicator must be at the end of non-grouping node | ||
if (node.isGroup) { | ||
stream.backUp(1); | ||
throw stream.error('Unexpected self-closing indicator'); | ||
} | ||
stream.next(); | ||
node.selfClosing = true; | ||
break; | ||
} else if (next = consumeAttributes(stream)) { | ||
for (let i = 0, il = next.length; i < il; i++) { | ||
node.setAttribute(next[i]); | ||
} | ||
} else if ((next = consumeTextNode(stream)) !== null) { | ||
node.value = next; | ||
} else if (next = consumeRepeat(stream)) { | ||
node.repeat = next; | ||
} else { | ||
@@ -661,0 +646,0 @@ break; |
@@ -459,10 +459,9 @@ /** | ||
var consumeRepeat = function(stream) { | ||
if (stream.next() !== '*') { | ||
stream.backUp(1); | ||
throw stream.error('Expected * character for repeater'); | ||
if (stream.eat('*')) { | ||
const value = stream.consume(/[0-9]/); | ||
// XXX think about extending repeat syntax with through numbering | ||
return {count: value ? +value : null}; | ||
} | ||
const value = stream.consume(/[0-9]/); | ||
// XXX think about extending repeat syntax with through numbering | ||
return {count: value ? +value : null}; | ||
return null; | ||
}; | ||
@@ -474,11 +473,11 @@ | ||
* @param {StringStream} stream | ||
* @return {String} | ||
* @return {String} Returns `null` if unable to consume quoted value from current | ||
* position | ||
*/ | ||
var consumeQuoted = function(stream) { | ||
const quote = stream.next(); | ||
if (!isQuote(quote)) { | ||
stream.backUp(1); | ||
throw stream.error('Expected single or double quote for string literal'); | ||
if (!isQuote(stream.peek())) { | ||
return null; | ||
} | ||
const quote = stream.next(); | ||
const start = stream.pos; | ||
@@ -495,16 +494,15 @@ if (!stream.skipQuoted(quote)) { | ||
* @param {StringStream} stream [description] | ||
* @return {String} | ||
* @return {String} Returns `null` if unable to consume text node from current | ||
* position | ||
*/ | ||
var consumeTextNode = function(stream) { | ||
if (stream.next() !== '{') { | ||
stream.backUp(1); | ||
throw stream.error('Expected { as a beginning of text node'); | ||
if (stream.peek() !== '{') { | ||
return null; | ||
} | ||
const start = stream.pos; | ||
let stack = 1; | ||
const start = stream.pos + 1; | ||
let stack = 0; | ||
while (!stream.eol()) { | ||
if (isQuote(stream.peek())) { | ||
consumeQuoted(stream); | ||
if (consumeQuoted(stream) !== null) { | ||
continue; | ||
@@ -543,4 +541,4 @@ } | ||
var consumeAttributes = function(stream) { | ||
if (stream.next() !== '[') { | ||
throw stream.error('Expected "[" brace'); | ||
if (!stream.eat('[')) { | ||
return null; | ||
} | ||
@@ -551,13 +549,12 @@ | ||
while (!stream.eol()) { | ||
stream.consume(reSpaceChar); | ||
const next = stream.peek(); | ||
stream.eatWhile(reSpaceChar); | ||
if (next === ']') { // end of attribute set | ||
stream.next(); | ||
if (stream.eat(']')) { // end of attribute set | ||
return result; | ||
} | ||
if (isQuote(next)) { | ||
let next = consumeQuoted(stream); | ||
if (next !== null) { | ||
// Found quoted default value | ||
result.push({name: null, value: consumeQuoted(stream)}); | ||
result.push({name: null, value: next}); | ||
continue; | ||
@@ -567,18 +564,17 @@ } | ||
// Consume next word: could be either attribute name or unquoted default value | ||
const nextWord = stream.consume(reUnquotedValueChar); | ||
if (!nextWord) { | ||
if (next = stream.consume(reUnquotedValueChar)) { | ||
if (!reAttributeName.test(next)) { | ||
result.push({name: null, value: next}); | ||
continue; | ||
} | ||
} else { | ||
throw stream.error('Expected attribute name or default value'); | ||
} | ||
if (!reAttributeName.test(nextWord)) { | ||
result.push({name: null, value: nextWord}); | ||
continue; | ||
} | ||
const attr = {name: nextWord}; | ||
const attr = {name: next}; | ||
result.push(attr); | ||
// Check for last character: if it’s a `.`, user wants boolean attribute | ||
if (nextWord[nextWord.length - 1] === '.') { | ||
attr.name = nextWord.slice(0, nextWord.length - 1); | ||
if (next[next.length - 1] === '.') { | ||
attr.name = next.slice(0, next.length - 1); | ||
attr.options = {boolean: true}; | ||
@@ -590,13 +586,7 @@ continue; | ||
// or React-like expression | ||
if (stream.peek() === '=') { | ||
stream.next(); | ||
const next = stream.peek(); | ||
if (isQuote(next)) { | ||
attr.value = consumeQuoted(stream); | ||
continue; | ||
} | ||
if (next === '{') { | ||
attr.value = consumeTextNode(stream); | ||
if (stream.eat('=')) { | ||
if ((next = consumeQuoted(stream)) !== null) { | ||
attr.value = next; | ||
} else if ((next = consumeTextNode(stream)) !== null) { | ||
attr.value = next; | ||
attr.options = { | ||
@@ -606,6 +596,5 @@ before: '{', | ||
}; | ||
continue; | ||
} else { | ||
attr.value = stream.consume(reUnquotedValueChar); | ||
} | ||
attr.value = stream.consume(reUnquotedValueChar); | ||
} | ||
@@ -626,33 +615,29 @@ } | ||
var consumeElement = function(stream) { | ||
const node = new Node(); | ||
// consume element name, if provided | ||
const start = stream.pos; | ||
const node = new Node(stream.consume(reNameChar)); | ||
while (!stream.eol()) { | ||
const ch = stream.peek(); | ||
let next; | ||
if (ch === '.') { | ||
stream.next(); | ||
if (stream.eat('.')) { | ||
node.addClass(stream.consume(reWordChar)); | ||
} else if (ch === '#') { | ||
stream.next(); | ||
} else if (stream.eat('#')) { | ||
node.setAttribute('id', stream.consume(reWordChar)); | ||
} else if (ch === '[') { | ||
const attrs = consumeAttributes(stream); | ||
for (let i = 0, il = attrs.length; i < il; i++) { | ||
node.setAttribute(attrs[i]); | ||
} | ||
} else if (ch === '{') { | ||
node.value = consumeTextNode(stream); | ||
} else if (reNameChar.test(ch) && stream.pos === start) { | ||
node.name = stream.consume(reNameChar); | ||
} else if (ch === '*') { | ||
node.repeat = consumeRepeat(stream); | ||
} else if (ch === '/') { | ||
} else if (stream.eat('/')) { | ||
// A self-closing indicator must be at the end of non-grouping node | ||
if (node.isGroup) { | ||
stream.backUp(1); | ||
throw stream.error('Unexpected self-closing indicator'); | ||
} | ||
stream.next(); | ||
node.selfClosing = true; | ||
break; | ||
} else if (next = consumeAttributes(stream)) { | ||
for (let i = 0, il = next.length; i < il; i++) { | ||
node.setAttribute(next[i]); | ||
} | ||
} else if ((next = consumeTextNode(stream)) !== null) { | ||
node.value = next; | ||
} else if (next = consumeRepeat(stream)) { | ||
node.repeat = next; | ||
} else { | ||
@@ -659,0 +644,0 @@ break; |
@@ -5,3 +5,2 @@ 'use strict'; | ||
import consumeTextNode from './text'; | ||
import { isQuote } from '../utils'; | ||
@@ -20,4 +19,4 @@ const reAttributeName = /^[\w\-:\$@]+\.?$/; | ||
export default function(stream) { | ||
if (stream.next() !== '[') { | ||
throw stream.error('Expected "[" brace'); | ||
if (!stream.eat('[')) { | ||
return null; | ||
} | ||
@@ -28,13 +27,12 @@ | ||
while (!stream.eol()) { | ||
stream.consume(reSpaceChar); | ||
const next = stream.peek(); | ||
stream.eatWhile(reSpaceChar); | ||
if (next === ']') { // end of attribute set | ||
stream.next(); | ||
if (stream.eat(']')) { // end of attribute set | ||
return result; | ||
} | ||
if (isQuote(next)) { | ||
let next = consumeQuoted(stream); | ||
if (next !== null) { | ||
// Found quoted default value | ||
result.push({name: null, value: consumeQuoted(stream)}); | ||
result.push({name: null, value: next}); | ||
continue; | ||
@@ -44,18 +42,17 @@ } | ||
// Consume next word: could be either attribute name or unquoted default value | ||
const nextWord = stream.consume(reUnquotedValueChar); | ||
if (!nextWord) { | ||
if (next = stream.consume(reUnquotedValueChar)) { | ||
if (!reAttributeName.test(next)) { | ||
result.push({name: null, value: next}); | ||
continue; | ||
} | ||
} else { | ||
throw stream.error('Expected attribute name or default value'); | ||
} | ||
if (!reAttributeName.test(nextWord)) { | ||
result.push({name: null, value: nextWord}); | ||
continue; | ||
} | ||
const attr = {name: nextWord}; | ||
const attr = {name: next}; | ||
result.push(attr); | ||
// Check for last character: if it’s a `.`, user wants boolean attribute | ||
if (nextWord[nextWord.length - 1] === '.') { | ||
attr.name = nextWord.slice(0, nextWord.length - 1); | ||
if (next[next.length - 1] === '.') { | ||
attr.name = next.slice(0, next.length - 1); | ||
attr.options = {boolean: true}; | ||
@@ -67,13 +64,7 @@ continue; | ||
// or React-like expression | ||
if (stream.peek() === '=') { | ||
stream.next(); | ||
const next = stream.peek(); | ||
if (isQuote(next)) { | ||
attr.value = consumeQuoted(stream); | ||
continue; | ||
} | ||
if (next === '{') { | ||
attr.value = consumeTextNode(stream); | ||
if (stream.eat('=')) { | ||
if ((next = consumeQuoted(stream)) !== null) { | ||
attr.value = next; | ||
} else if ((next = consumeTextNode(stream)) !== null) { | ||
attr.value = next; | ||
attr.options = { | ||
@@ -83,6 +74,5 @@ before: '{', | ||
} | ||
continue; | ||
} else { | ||
attr.value = stream.consume(reUnquotedValueChar); | ||
} | ||
attr.value = stream.consume(reUnquotedValueChar); | ||
} | ||
@@ -89,0 +79,0 @@ } |
@@ -17,33 +17,29 @@ 'use strict'; | ||
export default function(stream) { | ||
const node = new Node(); | ||
// consume element name, if provided | ||
const start = stream.pos; | ||
const node = new Node(stream.consume(reNameChar)); | ||
while (!stream.eol()) { | ||
const ch = stream.peek(); | ||
let next; | ||
if (ch === '.') { | ||
stream.next(); | ||
if (stream.eat('.')) { | ||
node.addClass(stream.consume(reWordChar)); | ||
} else if (ch === '#') { | ||
stream.next(); | ||
} else if (stream.eat('#')) { | ||
node.setAttribute('id', stream.consume(reWordChar)); | ||
} else if (ch === '[') { | ||
const attrs = consumeAttributes(stream); | ||
for (let i = 0, il = attrs.length; i < il; i++) { | ||
node.setAttribute(attrs[i]); | ||
} | ||
} else if (ch === '{') { | ||
node.value = consumeTextNode(stream); | ||
} else if (reNameChar.test(ch) && stream.pos === start) { | ||
node.name = stream.consume(reNameChar); | ||
} else if (ch === '*') { | ||
node.repeat = consumeRepeat(stream); | ||
} else if (ch === '/') { | ||
} else if (stream.eat('/')) { | ||
// A self-closing indicator must be at the end of non-grouping node | ||
if (node.isGroup) { | ||
stream.backUp(1); | ||
throw stream.error('Unexpected self-closing indicator'); | ||
} | ||
stream.next(); | ||
node.selfClosing = true; | ||
break; | ||
} else if (next = consumeAttributes(stream)) { | ||
for (let i = 0, il = next.length; i < il; i++) { | ||
node.setAttribute(next[i]); | ||
} | ||
} else if ((next = consumeTextNode(stream)) !== null) { | ||
node.value = next; | ||
} else if (next = consumeRepeat(stream)) { | ||
node.repeat = next; | ||
} else { | ||
@@ -50,0 +46,0 @@ break; |
@@ -9,11 +9,11 @@ 'use strict'; | ||
* @param {StringStream} stream | ||
* @return {String} | ||
* @return {String} Returns `null` if unable to consume quoted value from current | ||
* position | ||
*/ | ||
export default function(stream) { | ||
const quote = stream.next(); | ||
if (!isQuote(quote)) { | ||
stream.backUp(1); | ||
throw stream.error('Expected single or double quote for string literal'); | ||
if (!isQuote(stream.peek())) { | ||
return null; | ||
} | ||
const quote = stream.next(); | ||
const start = stream.pos; | ||
@@ -20,0 +20,0 @@ if (!stream.skipQuoted(quote)) { |
@@ -10,10 +10,9 @@ 'use strict'; | ||
export default function(stream) { | ||
if (stream.next() !== '*') { | ||
stream.backUp(1); | ||
throw stream.error('Expected * character for repeater'); | ||
if (stream.eat('*')) { | ||
const value = stream.consume(/[0-9]/); | ||
// XXX think about extending repeat syntax with through numbering | ||
return {count: value ? +value : null}; | ||
} | ||
const value = stream.consume(/[0-9]/); | ||
// XXX think about extending repeat syntax with through numbering | ||
return {count: value ? +value : null}; | ||
return null; | ||
} |
'use strict'; | ||
import consumeQuoted from './quoted'; | ||
import { isQuote } from '../utils'; | ||
@@ -9,16 +8,15 @@ /** | ||
* @param {StringStream} stream [description] | ||
* @return {String} | ||
* @return {String} Returns `null` if unable to consume text node from current | ||
* position | ||
*/ | ||
export default function(stream) { | ||
if (stream.next() !== '{') { | ||
stream.backUp(1); | ||
throw stream.error('Expected { as a beginning of text node'); | ||
if (stream.peek() !== '{') { | ||
return null; | ||
} | ||
const start = stream.pos; | ||
let stack = 1; | ||
const start = stream.pos + 1; | ||
let stack = 0; | ||
while (!stream.eol()) { | ||
if (isQuote(stream.peek())) { | ||
consumeQuoted(stream); | ||
if (consumeQuoted(stream) !== null) { | ||
continue; | ||
@@ -25,0 +23,0 @@ } |
{ | ||
"name": "@emmetio/abbreviation", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Emmet standalone abbreviation parser", | ||
@@ -5,0 +5,0 @@ "main": "dist/abbreviation.cjs.js", |
@@ -80,4 +80,2 @@ 'use strict'; | ||
}); | ||
// TODO implement forced void element | ||
}); |
@@ -17,6 +17,2 @@ 'use strict'; | ||
}); | ||
it('error', () => { | ||
assert.throws(() => parse('123'), /Expected \* character for repeater/); | ||
}); | ||
}); |
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
82874
2951