1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const stringUtils_1 = require("./utils/stringUtils");
|
4 | const CommentChar_1 = require("./CommentChar");
|
5 |
|
6 | const CHARS = {
|
7 | BACK_SLASH: "\\".charCodeAt(0),
|
8 | FORWARD_SLASH: "/".charCodeAt(0),
|
9 | NEW_LINE: "\n".charCodeAt(0),
|
10 | CARRIAGE_RETURN: "\r".charCodeAt(0),
|
11 | ASTERISK: "*".charCodeAt(0),
|
12 | DOUBLE_QUOTE: "\"".charCodeAt(0),
|
13 | SINGLE_QUOTE: "'".charCodeAt(0),
|
14 | BACK_TICK: "`".charCodeAt(0),
|
15 | OPEN_BRACE: "{".charCodeAt(0),
|
16 | CLOSE_BRACE: "}".charCodeAt(0),
|
17 | DOLLAR_SIGN: "$".charCodeAt(0),
|
18 | };
|
19 | const isCharToHandle = new Set([
|
20 | CHARS.BACK_SLASH,
|
21 | CHARS.FORWARD_SLASH,
|
22 | CHARS.NEW_LINE,
|
23 | CHARS.CARRIAGE_RETURN,
|
24 | CHARS.ASTERISK,
|
25 | CHARS.DOUBLE_QUOTE,
|
26 | CHARS.SINGLE_QUOTE,
|
27 | CHARS.BACK_TICK,
|
28 | CHARS.OPEN_BRACE,
|
29 | CHARS.CLOSE_BRACE,
|
30 | ]);
|
31 |
|
32 |
|
33 |
|
34 | class CodeBlockWriter {
|
35 | |
36 |
|
37 |
|
38 |
|
39 | constructor(opts = {}) {
|
40 |
|
41 | this._currentIndentation = 0;
|
42 |
|
43 | this._length = 0;
|
44 |
|
45 | this._newLineOnNextWrite = false;
|
46 |
|
47 | this._currentCommentChar = undefined;
|
48 |
|
49 | this._stringCharStack = [];
|
50 |
|
51 | this._isInRegEx = false;
|
52 |
|
53 | this._isOnFirstLineOfBlock = true;
|
54 |
|
55 |
|
56 |
|
57 | this._texts = [];
|
58 | this._newLine = opts.newLine || "\n";
|
59 | this._useTabs = opts.useTabs || false;
|
60 | this._indentNumberOfSpaces = opts.indentNumberOfSpaces || 4;
|
61 | this._indentationText = getIndentationText(this._useTabs, this._indentNumberOfSpaces);
|
62 | this._quoteChar = opts.useSingleQuote ? "'" : `"`;
|
63 | }
|
64 | |
65 |
|
66 |
|
67 | getOptions() {
|
68 | return {
|
69 | indentNumberOfSpaces: this._indentNumberOfSpaces,
|
70 | newLine: this._newLine,
|
71 | useTabs: this._useTabs,
|
72 | useSingleQuote: this._quoteChar === "'",
|
73 | };
|
74 | }
|
75 | queueIndentationLevel(countOrText) {
|
76 | this._queuedIndentation = this._getIndentationLevelFromArg(countOrText);
|
77 | this._queuedOnlyIfNotBlock = undefined;
|
78 | return this;
|
79 | }
|
80 | |
81 |
|
82 |
|
83 |
|
84 | hangingIndent(action) {
|
85 | return this._withResetIndentation(() => this.queueIndentationLevel(this.getIndentationLevel() + 1), action);
|
86 | }
|
87 | |
88 |
|
89 |
|
90 |
|
91 | hangingIndentUnlessBlock(action) {
|
92 | return this._withResetIndentation(() => {
|
93 | this.queueIndentationLevel(this.getIndentationLevel() + 1);
|
94 | this._queuedOnlyIfNotBlock = true;
|
95 | }, action);
|
96 | }
|
97 | setIndentationLevel(countOrText) {
|
98 | this._currentIndentation = this._getIndentationLevelFromArg(countOrText);
|
99 | return this;
|
100 | }
|
101 | withIndentationLevel(countOrText, action) {
|
102 | return this._withResetIndentation(() => this.setIndentationLevel(countOrText), action);
|
103 | }
|
104 |
|
105 | _withResetIndentation(setStateAction, writeAction) {
|
106 | const previousState = this._getIndentationState();
|
107 | setStateAction();
|
108 | try {
|
109 | writeAction();
|
110 | }
|
111 | finally {
|
112 | this._setIndentationState(previousState);
|
113 | }
|
114 | return this;
|
115 | }
|
116 | |
117 |
|
118 |
|
119 | getIndentationLevel() {
|
120 | return this._currentIndentation;
|
121 | }
|
122 | |
123 |
|
124 |
|
125 |
|
126 | block(block) {
|
127 | this._newLineIfNewLineOnNextWrite();
|
128 | if (this.getLength() > 0 && !this.isLastNewLine())
|
129 | this.spaceIfLastNot();
|
130 | this.inlineBlock(block);
|
131 | this._newLineOnNextWrite = true;
|
132 | return this;
|
133 | }
|
134 | |
135 |
|
136 |
|
137 |
|
138 | inlineBlock(block) {
|
139 | this._newLineIfNewLineOnNextWrite();
|
140 | this.write("{");
|
141 | this._indentBlockInternal(block);
|
142 | this.newLineIfLastNot().write("}");
|
143 | return this;
|
144 | }
|
145 | indent(timesOrBlock = 1) {
|
146 | if (typeof timesOrBlock === "number") {
|
147 | this._newLineIfNewLineOnNextWrite();
|
148 | return this.write(this._indentationText.repeat(timesOrBlock));
|
149 | }
|
150 | else {
|
151 | this._indentBlockInternal(timesOrBlock);
|
152 | if (!this.isLastNewLine())
|
153 | this._newLineOnNextWrite = true;
|
154 | return this;
|
155 | }
|
156 | }
|
157 |
|
158 | _indentBlockInternal(block) {
|
159 | if (this.getLastChar() != null)
|
160 | this.newLineIfLastNot();
|
161 | this._currentIndentation++;
|
162 | this._isOnFirstLineOfBlock = true;
|
163 | if (block != null)
|
164 | block();
|
165 | this._isOnFirstLineOfBlock = false;
|
166 | this._currentIndentation = Math.max(0, this._currentIndentation - 1);
|
167 | }
|
168 | conditionalWriteLine(condition, strOrFunc) {
|
169 | if (condition)
|
170 | this.writeLine(stringUtils_1.getStringFromStrOrFunc(strOrFunc));
|
171 | return this;
|
172 | }
|
173 | |
174 |
|
175 |
|
176 |
|
177 | writeLine(text) {
|
178 | this._newLineIfNewLineOnNextWrite();
|
179 | if (this.getLastChar() != null)
|
180 | this.newLineIfLastNot();
|
181 | this._writeIndentingNewLines(text);
|
182 | this.newLine();
|
183 | return this;
|
184 | }
|
185 | |
186 |
|
187 |
|
188 | newLineIfLastNot() {
|
189 | this._newLineIfNewLineOnNextWrite();
|
190 | if (!this.isLastNewLine())
|
191 | this.newLine();
|
192 | return this;
|
193 | }
|
194 | |
195 |
|
196 |
|
197 | blankLineIfLastNot() {
|
198 | if (!this.isLastBlankLine())
|
199 | this.blankLine();
|
200 | return this;
|
201 | }
|
202 | |
203 |
|
204 |
|
205 |
|
206 | conditionalBlankLine(condition) {
|
207 | if (condition)
|
208 | this.blankLine();
|
209 | return this;
|
210 | }
|
211 | |
212 |
|
213 |
|
214 | blankLine() {
|
215 | return this.newLineIfLastNot().newLine();
|
216 | }
|
217 | |
218 |
|
219 |
|
220 |
|
221 | conditionalNewLine(condition) {
|
222 | if (condition)
|
223 | this.newLine();
|
224 | return this;
|
225 | }
|
226 | |
227 |
|
228 |
|
229 | newLine() {
|
230 | this._newLineOnNextWrite = false;
|
231 | this._baseWriteNewline();
|
232 | return this;
|
233 | }
|
234 | quote(text) {
|
235 | this._newLineIfNewLineOnNextWrite();
|
236 | this._writeIndentingNewLines(text == null ? this._quoteChar : this._quoteChar + stringUtils_1.escapeForWithinString(text, this._quoteChar) + this._quoteChar);
|
237 | return this;
|
238 | }
|
239 | |
240 |
|
241 |
|
242 | spaceIfLastNot() {
|
243 | this._newLineIfNewLineOnNextWrite();
|
244 | if (!this.isLastSpace())
|
245 | this._writeIndentingNewLines(" ");
|
246 | return this;
|
247 | }
|
248 | |
249 |
|
250 |
|
251 |
|
252 | space(times = 1) {
|
253 | this._newLineIfNewLineOnNextWrite();
|
254 | this._writeIndentingNewLines(" ".repeat(times));
|
255 | return this;
|
256 | }
|
257 | |
258 |
|
259 |
|
260 | tabIfLastNot() {
|
261 | this._newLineIfNewLineOnNextWrite();
|
262 | if (!this.isLastTab())
|
263 | this._writeIndentingNewLines("\t");
|
264 | return this;
|
265 | }
|
266 | |
267 |
|
268 |
|
269 |
|
270 | tab(times = 1) {
|
271 | this._newLineIfNewLineOnNextWrite();
|
272 | this._writeIndentingNewLines("\t".repeat(times));
|
273 | return this;
|
274 | }
|
275 | conditionalWrite(condition, textOrFunc) {
|
276 | if (condition)
|
277 | this.write(stringUtils_1.getStringFromStrOrFunc(textOrFunc));
|
278 | return this;
|
279 | }
|
280 | |
281 |
|
282 |
|
283 |
|
284 | write(text) {
|
285 | this._newLineIfNewLineOnNextWrite();
|
286 | this._writeIndentingNewLines(text);
|
287 | return this;
|
288 | }
|
289 | |
290 |
|
291 |
|
292 | closeComment() {
|
293 | const commentChar = this._currentCommentChar;
|
294 | switch (commentChar) {
|
295 | case CommentChar_1.CommentChar.Line:
|
296 | this.newLine();
|
297 | break;
|
298 | case CommentChar_1.CommentChar.Star:
|
299 | if (!this.isLastNewLine())
|
300 | this.spaceIfLastNot();
|
301 | this.write("*/");
|
302 | break;
|
303 | default:
|
304 | const assertUndefined = commentChar;
|
305 | break;
|
306 | }
|
307 | return this;
|
308 | }
|
309 | |
310 |
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 | unsafeInsert(pos, text) {
|
320 | const textLength = this._length;
|
321 | const texts = this._texts;
|
322 | verifyInput();
|
323 | if (pos === textLength)
|
324 | return this.write(text);
|
325 | updateInternalArray();
|
326 | this._length += text.length;
|
327 | return this;
|
328 | function verifyInput() {
|
329 | if (pos < 0)
|
330 | throw new Error(`Provided position of '${pos}' was less than zero.`);
|
331 | if (pos > textLength)
|
332 | throw new Error(`Provided position of '${pos}' was greater than the text length of '${textLength}'.`);
|
333 | }
|
334 | function updateInternalArray() {
|
335 | const { index, localIndex } = getArrayIndexAndLocalIndex();
|
336 | if (localIndex === 0)
|
337 | texts.splice(index, 0, text);
|
338 | else if (localIndex === texts[index].length)
|
339 | texts.splice(index + 1, 0, text);
|
340 | else {
|
341 | const textItem = texts[index];
|
342 | const startText = textItem.substring(0, localIndex);
|
343 | const endText = textItem.substring(localIndex);
|
344 | texts.splice(index, 1, startText, text, endText);
|
345 | }
|
346 | }
|
347 | function getArrayIndexAndLocalIndex() {
|
348 | if (pos < textLength / 2) {
|
349 |
|
350 | let endPos = 0;
|
351 | for (let i = 0; i < texts.length; i++) {
|
352 | const textItem = texts[i];
|
353 | const startPos = endPos;
|
354 | endPos += textItem.length;
|
355 | if (endPos >= pos)
|
356 | return { index: i, localIndex: pos - startPos };
|
357 | }
|
358 | }
|
359 | else {
|
360 |
|
361 | let startPos = textLength;
|
362 | for (let i = texts.length - 1; i >= 0; i--) {
|
363 | const textItem = texts[i];
|
364 | startPos -= textItem.length;
|
365 | if (startPos <= pos)
|
366 | return { index: i, localIndex: pos - startPos };
|
367 | }
|
368 | }
|
369 | throw new Error("Unhandled situation inserting. This should never happen.");
|
370 | }
|
371 | }
|
372 | |
373 |
|
374 |
|
375 | getLength() {
|
376 | return this._length;
|
377 | }
|
378 | |
379 |
|
380 |
|
381 | isInComment() {
|
382 | return this._currentCommentChar !== undefined;
|
383 | }
|
384 | |
385 |
|
386 |
|
387 | isAtStartOfFirstLineOfBlock() {
|
388 | return this.isOnFirstLineOfBlock() && (this.isLastNewLine() || this.getLastChar() == null);
|
389 | }
|
390 | |
391 |
|
392 |
|
393 | isOnFirstLineOfBlock() {
|
394 | return this._isOnFirstLineOfBlock;
|
395 | }
|
396 | |
397 |
|
398 |
|
399 | isInString() {
|
400 | return this._stringCharStack.length > 0 && this._stringCharStack[this._stringCharStack.length - 1] !== CHARS.OPEN_BRACE;
|
401 | }
|
402 | |
403 |
|
404 |
|
405 | isLastNewLine() {
|
406 | const lastChar = this.getLastChar();
|
407 | return lastChar === "\n" || lastChar === "\r";
|
408 | }
|
409 | |
410 |
|
411 |
|
412 | isLastBlankLine() {
|
413 | let foundCount = 0;
|
414 |
|
415 |
|
416 | for (let i = this._texts.length - 1; i >= 0; i--) {
|
417 | const currentText = this._texts[i];
|
418 | for (let j = currentText.length - 1; j >= 0; j--) {
|
419 | const currentChar = currentText.charCodeAt(j);
|
420 | if (currentChar === CHARS.NEW_LINE) {
|
421 | foundCount++;
|
422 | if (foundCount === 2)
|
423 | return true;
|
424 | }
|
425 | else if (currentChar !== CHARS.CARRIAGE_RETURN) {
|
426 | return false;
|
427 | }
|
428 | }
|
429 | }
|
430 | return false;
|
431 | }
|
432 | |
433 |
|
434 |
|
435 | isLastSpace() {
|
436 | return this.getLastChar() === " ";
|
437 | }
|
438 | |
439 |
|
440 |
|
441 | isLastTab() {
|
442 | return this.getLastChar() === "\t";
|
443 | }
|
444 | |
445 |
|
446 |
|
447 | getLastChar() {
|
448 | const charCode = this._getLastCharCodeWithOffset(0);
|
449 | return charCode == null ? undefined : String.fromCharCode(charCode);
|
450 | }
|
451 | |
452 |
|
453 |
|
454 |
|
455 | endsWith(text) {
|
456 | const length = this._length;
|
457 | return this.iterateLastCharCodes((charCode, index) => {
|
458 | const offset = length - index;
|
459 | const textIndex = text.length - offset;
|
460 | if (text.charCodeAt(textIndex) !== charCode)
|
461 | return false;
|
462 | return textIndex === 0 ? true : undefined;
|
463 | }) || false;
|
464 | }
|
465 | |
466 |
|
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 | iterateLastChars(action) {
|
473 | return this.iterateLastCharCodes((charCode, index) => action(String.fromCharCode(charCode), index));
|
474 | }
|
475 | |
476 |
|
477 |
|
478 |
|
479 |
|
480 |
|
481 |
|
482 |
|
483 | iterateLastCharCodes(action) {
|
484 | let index = this._length;
|
485 | for (let i = this._texts.length - 1; i >= 0; i--) {
|
486 | const currentText = this._texts[i];
|
487 | for (let j = currentText.length - 1; j >= 0; j--) {
|
488 | index--;
|
489 | const result = action(currentText.charCodeAt(j), index);
|
490 | if (result != null)
|
491 | return result;
|
492 | }
|
493 | }
|
494 | return undefined;
|
495 | }
|
496 | |
497 |
|
498 |
|
499 | toString() {
|
500 | if (this._texts.length > 1) {
|
501 | const text = this._texts.join("");
|
502 | this._texts.length = 0;
|
503 | this._texts.push(text);
|
504 | }
|
505 | return this._texts[0] || "";
|
506 | }
|
507 |
|
508 | _writeIndentingNewLines(text) {
|
509 | text = text || "";
|
510 | if (text.length === 0) {
|
511 | writeIndividual(this, "");
|
512 | return;
|
513 | }
|
514 | const items = text.split(CodeBlockWriter._newLineRegEx);
|
515 | items.forEach((s, i) => {
|
516 | if (i > 0)
|
517 | this._baseWriteNewline();
|
518 | if (s.length === 0)
|
519 | return;
|
520 | writeIndividual(this, s);
|
521 | });
|
522 | function writeIndividual(writer, s) {
|
523 | if (!writer.isInString()) {
|
524 | const isAtStartOfLine = writer.isLastNewLine() || writer.getLastChar() == null;
|
525 | if (isAtStartOfLine)
|
526 | writer._writeIndentation();
|
527 | }
|
528 | writer._updateInternalState(s);
|
529 | writer._internalWrite(s);
|
530 | }
|
531 | }
|
532 |
|
533 | _baseWriteNewline() {
|
534 | if (this._currentCommentChar === CommentChar_1.CommentChar.Line)
|
535 | this._currentCommentChar = undefined;
|
536 | const lastStringCharOnStack = this._stringCharStack[this._stringCharStack.length - 1];
|
537 | if ((lastStringCharOnStack === CHARS.DOUBLE_QUOTE || lastStringCharOnStack === CHARS.SINGLE_QUOTE) && this._getLastCharCodeWithOffset(0) !== CHARS.BACK_SLASH)
|
538 | this._stringCharStack.pop();
|
539 | this._internalWrite(this._newLine);
|
540 | this._isOnFirstLineOfBlock = false;
|
541 | this._dequeueQueuedIndentation();
|
542 | }
|
543 |
|
544 | _dequeueQueuedIndentation() {
|
545 | if (this._queuedIndentation == null)
|
546 | return;
|
547 | if (this._queuedOnlyIfNotBlock && wasLastBlock(this)) {
|
548 | this._queuedIndentation = undefined;
|
549 | this._queuedOnlyIfNotBlock = undefined;
|
550 | }
|
551 | else {
|
552 | this._currentIndentation = this._queuedIndentation;
|
553 | this._queuedIndentation = undefined;
|
554 | }
|
555 | function wasLastBlock(writer) {
|
556 | let foundNewLine = false;
|
557 | return writer.iterateLastCharCodes(charCode => {
|
558 | switch (charCode) {
|
559 | case CHARS.NEW_LINE:
|
560 | if (foundNewLine)
|
561 | return false;
|
562 | else
|
563 | foundNewLine = true;
|
564 | break;
|
565 | case CHARS.CARRIAGE_RETURN:
|
566 | return undefined;
|
567 | case CHARS.OPEN_BRACE:
|
568 | return true;
|
569 | default:
|
570 | return false;
|
571 | }
|
572 | });
|
573 | }
|
574 | }
|
575 |
|
576 | _updateInternalState(str) {
|
577 | for (let i = 0; i < str.length; i++) {
|
578 | const currentChar = str.charCodeAt(i);
|
579 |
|
580 |
|
581 |
|
582 | if (!isCharToHandle.has(currentChar))
|
583 | continue;
|
584 | const pastChar = i === 0 ? this._getLastCharCodeWithOffset(0) : str.charCodeAt(i - 1);
|
585 | const pastPastChar = i === 0 ? this._getLastCharCodeWithOffset(1) : i === 1 ? this._getLastCharCodeWithOffset(0) : str.charCodeAt(i - 2);
|
586 |
|
587 | if (this._isInRegEx) {
|
588 | if (pastChar === CHARS.FORWARD_SLASH && pastPastChar !== CHARS.BACK_SLASH || pastChar === CHARS.NEW_LINE)
|
589 | this._isInRegEx = false;
|
590 | else
|
591 | continue;
|
592 | }
|
593 | else if (!this.isInString() && !this.isInComment() && isRegExStart(currentChar, pastChar, pastPastChar)) {
|
594 | this._isInRegEx = true;
|
595 | continue;
|
596 | }
|
597 |
|
598 | if (this._currentCommentChar == null && pastChar === CHARS.FORWARD_SLASH && currentChar === CHARS.FORWARD_SLASH)
|
599 | this._currentCommentChar = CommentChar_1.CommentChar.Line;
|
600 | else if (this._currentCommentChar == null && pastChar === CHARS.FORWARD_SLASH && currentChar === CHARS.ASTERISK)
|
601 | this._currentCommentChar = CommentChar_1.CommentChar.Star;
|
602 | else if (this._currentCommentChar === CommentChar_1.CommentChar.Star && pastChar === CHARS.ASTERISK && currentChar === CHARS.FORWARD_SLASH)
|
603 | this._currentCommentChar = undefined;
|
604 | if (this.isInComment())
|
605 | continue;
|
606 |
|
607 | const lastStringCharOnStack = this._stringCharStack.length === 0 ? undefined : this._stringCharStack[this._stringCharStack.length - 1];
|
608 | if (pastChar !== CHARS.BACK_SLASH && (currentChar === CHARS.DOUBLE_QUOTE || currentChar === CHARS.SINGLE_QUOTE || currentChar === CHARS.BACK_TICK)) {
|
609 | if (lastStringCharOnStack === currentChar)
|
610 | this._stringCharStack.pop();
|
611 | else if (lastStringCharOnStack === CHARS.OPEN_BRACE || lastStringCharOnStack === undefined)
|
612 | this._stringCharStack.push(currentChar);
|
613 | }
|
614 | else if (pastPastChar !== CHARS.BACK_SLASH && pastChar === CHARS.DOLLAR_SIGN && currentChar === CHARS.OPEN_BRACE && lastStringCharOnStack === CHARS.BACK_TICK)
|
615 | this._stringCharStack.push(currentChar);
|
616 | else if (currentChar === CHARS.CLOSE_BRACE && lastStringCharOnStack === CHARS.OPEN_BRACE)
|
617 | this._stringCharStack.pop();
|
618 | }
|
619 | }
|
620 |
|
621 | _getLastCharCodeWithOffset(offset) {
|
622 | if (offset >= this._length || offset < 0)
|
623 | return undefined;
|
624 | for (let i = this._texts.length - 1; i >= 0; i--) {
|
625 | const currentText = this._texts[i];
|
626 | if (offset >= currentText.length)
|
627 | offset -= currentText.length;
|
628 | else
|
629 | return currentText.charCodeAt(currentText.length - 1 - offset);
|
630 | }
|
631 | return undefined;
|
632 | }
|
633 |
|
634 | _writeIndentation() {
|
635 | const flooredIndentation = Math.floor(this._currentIndentation);
|
636 | this._internalWrite(this._indentationText.repeat(flooredIndentation));
|
637 | const overflow = this._currentIndentation - flooredIndentation;
|
638 | if (this._useTabs) {
|
639 | if (overflow > 0.5)
|
640 | this._internalWrite(this._indentationText);
|
641 | }
|
642 | else {
|
643 | const portion = Math.round(this._indentationText.length * overflow);
|
644 |
|
645 | let text = "";
|
646 | for (let i = 0; i < portion; i++)
|
647 | text += this._indentationText[i];
|
648 | this._internalWrite(text);
|
649 | }
|
650 | }
|
651 |
|
652 | _newLineIfNewLineOnNextWrite() {
|
653 | if (!this._newLineOnNextWrite)
|
654 | return;
|
655 | this._newLineOnNextWrite = false;
|
656 | this.newLine();
|
657 | }
|
658 |
|
659 | _internalWrite(text) {
|
660 | if (text.length === 0)
|
661 | return;
|
662 | this._texts.push(text);
|
663 | this._length += text.length;
|
664 | }
|
665 |
|
666 | _getIndentationLevelFromArg(countOrText) {
|
667 | if (typeof countOrText === "number") {
|
668 | if (countOrText < 0)
|
669 | throw new Error("Passed in indentation level should be greater than or equal to 0.");
|
670 | return countOrText;
|
671 | }
|
672 | else if (typeof countOrText === "string") {
|
673 | if (!CodeBlockWriter._spacesOrTabsRegEx.test(countOrText))
|
674 | throw new Error("Provided string must be empty or only contain spaces or tabs.");
|
675 | const { spacesCount, tabsCount } = getSpacesAndTabsCount(countOrText);
|
676 | return tabsCount + spacesCount / this._indentNumberOfSpaces;
|
677 | }
|
678 | else {
|
679 | throw new Error("Argument provided must be a string or number.");
|
680 | }
|
681 | }
|
682 |
|
683 | _setIndentationState(state) {
|
684 | this._currentIndentation = state.current;
|
685 | this._queuedIndentation = state.queued;
|
686 | this._queuedOnlyIfNotBlock = state.queuedOnlyIfNotBlock;
|
687 | }
|
688 |
|
689 | _getIndentationState() {
|
690 | return {
|
691 | current: this._currentIndentation,
|
692 | queued: this._queuedIndentation,
|
693 | queuedOnlyIfNotBlock: this._queuedOnlyIfNotBlock,
|
694 | };
|
695 | }
|
696 | }
|
697 | exports.default = CodeBlockWriter;
|
698 |
|
699 | CodeBlockWriter._newLineRegEx = /\r?\n/;
|
700 |
|
701 | CodeBlockWriter._spacesOrTabsRegEx = /^[ \t]*$/;
|
702 | function isRegExStart(currentChar, pastChar, pastPastChar) {
|
703 | return pastChar === CHARS.FORWARD_SLASH
|
704 | && currentChar !== CHARS.FORWARD_SLASH
|
705 | && currentChar !== CHARS.ASTERISK
|
706 | && pastPastChar !== CHARS.ASTERISK
|
707 | && pastPastChar !== CHARS.FORWARD_SLASH;
|
708 | }
|
709 | function getIndentationText(useTabs, numberSpaces) {
|
710 | if (useTabs)
|
711 | return "\t";
|
712 | return Array(numberSpaces + 1).join(" ");
|
713 | }
|
714 | function getSpacesAndTabsCount(str) {
|
715 | let spacesCount = 0;
|
716 | let tabsCount = 0;
|
717 | for (const char of str) {
|
718 | if (char === " ")
|
719 | spacesCount++;
|
720 | else if (char === "\t")
|
721 | tabsCount++;
|
722 | }
|
723 | return { spacesCount, tabsCount };
|
724 | }
|