source: frontend/node_modules/strip-comments/lib/parse.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 3.3 KB
Line 
1'use strict';
2
3const { Node, Block } = require('./Node');
4const languages = require('./languages');
5
6const constants = {
7 ESCAPED_CHAR_REGEX: /^\\./,
8 QUOTED_STRING_REGEX: /^(['"`])((?:\\.|[^\1])+?)(\1)/,
9 NEWLINE_REGEX: /^\r*\n/
10};
11
12const parse = (input, options = {}) => {
13 if (typeof input !== 'string') {
14 throw new TypeError('Expected input to be a string');
15 }
16
17 const cst = new Block({ type: 'root', nodes: [] });
18 const stack = [cst];
19 const name = (options.language || 'javascript').toLowerCase();
20 const lang = languages[name];
21
22 if (typeof lang === 'undefined') {
23 throw new Error(`Language "${name}" is not supported by strip-comments`);
24 }
25
26 const { LINE_REGEX, BLOCK_OPEN_REGEX, BLOCK_CLOSE_REGEX } = lang;
27 let block = cst;
28 let remaining = input;
29 let token;
30 let prev;
31
32 const source = [BLOCK_OPEN_REGEX, BLOCK_CLOSE_REGEX].filter(Boolean);
33 let tripleQuotes = false;
34
35 if (source.every(regex => regex.source === '^"""')) {
36 tripleQuotes = true;
37 }
38
39 /**
40 * Helpers
41 */
42
43 const consume = (value = remaining[0] || '') => {
44 remaining = remaining.slice(value.length);
45 return value;
46 };
47
48 const scan = (regex, type = 'text') => {
49 const match = regex.exec(remaining);
50 if (match) {
51 consume(match[0]);
52 return { type, value: match[0], match };
53 }
54 };
55
56 const push = node => {
57 if (prev && prev.type === 'text' && node.type === 'text') {
58 prev.value += node.value;
59 return;
60 }
61 block.push(node);
62 if (node.nodes) {
63 stack.push(node);
64 block = node;
65 }
66 prev = node;
67 };
68
69 const pop = () => {
70 if (block.type === 'root') {
71 throw new SyntaxError('Unclosed block comment');
72 }
73 stack.pop();
74 block = stack[stack.length - 1];
75 };
76
77 /**
78 * Parse input string
79 */
80
81 while (remaining !== '') {
82 // escaped characters
83 if ((token = scan(constants.ESCAPED_CHAR_REGEX, 'text'))) {
84 push(new Node(token));
85 continue;
86 }
87
88 // quoted strings
89 if (block.type !== 'block' && (!prev || !/\w$/.test(prev.value)) && !(tripleQuotes && remaining.startsWith('"""'))) {
90 if ((token = scan(constants.QUOTED_STRING_REGEX, 'text'))) {
91 push(new Node(token));
92 continue;
93 }
94 }
95
96 // newlines
97 if ((token = scan(constants.NEWLINE_REGEX, 'newline'))) {
98 push(new Node(token));
99 continue;
100 }
101
102 // block comment open
103 if (BLOCK_OPEN_REGEX && options.block && !(tripleQuotes && block.type === 'block')) {
104 if ((token = scan(BLOCK_OPEN_REGEX, 'open'))) {
105 push(new Block({ type: 'block' }));
106 push(new Node(token));
107 continue;
108 }
109 }
110
111 // block comment close
112 if (BLOCK_CLOSE_REGEX && block.type === 'block' && options.block) {
113 if ((token = scan(BLOCK_CLOSE_REGEX, 'close'))) {
114 token.newline = token.match[1] || '';
115 push(new Node(token));
116 pop();
117 continue;
118 }
119 }
120
121 // line comment
122 if (LINE_REGEX && block.type !== 'block' && options.line) {
123 if ((token = scan(LINE_REGEX, 'line'))) {
124 push(new Node(token));
125 continue;
126 }
127 }
128
129 // Plain text (skip "C" since some languages use "C" to start comments)
130 if ((token = scan(/^[a-zABD-Z0-9\t ]+/, 'text'))) {
131 push(new Node(token));
132 continue;
133 }
134
135 push(new Node({ type: 'text', value: consume(remaining[0]) }));
136 }
137
138 return cst;
139};
140
141module.exports = parse;
Note: See TracBrowser for help on using the repository browser.