-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstring.js
66 lines (56 loc) · 1.64 KB
/
string.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
'use strict';
import { isQuote } from '@emmetio/stream-reader-utils';
import Token from './token';
import interpolation from './interpolation';
/**
* Consumes quoted string from current string and returns token with consumed
* data or `null`, if string wasn’t consumed
* @param {StreamReader} stream
* @return {StringToken}
*/
export default function string(stream) {
return eatString(stream, true);
}
export function eatString(stream, asToken) {
let ch = stream.peek(), pos, tokens, token;
if (isQuote(ch)) {
stream.start = stream.pos;
stream.next();
const quote = ch;
const valueStart = stream.pos;
while (!stream.eof()) {
pos = stream.pos;
if (stream.eat(quote) || stream.eat(isNewline)) {
// found end of string or newline without preceding '\',
// which is not allowed (don’t throw error, for now)
break;
} else if (stream.eat(92 /* \ */)) {
// backslash allows newline in string
stream.eat(isNewline);
} else if (asToken && (token = interpolation(stream))) {
if (!tokens) {
tokens = [token];
} else {
tokens.push(token);
}
}
stream.next();
}
// Either reached EOF or explicitly stopped at string end
// NB use extra `asToken` param to return boolean instead of token to reduce
// memory allocations and improve performance
if (asToken) {
const token = new Token(stream, 'string');
const inner = new Token(stream, 'unquoted', valueStart, pos);
inner.add(tokens);
token.add(inner);
token.property('quote', quote);
return token;
}
return true;
}
return false;
}
function isNewline(code) {
return code === 10 /* LF */ || code === 13 /* CR */;
}