Spaces:
Running
Running
File size: 4,824 Bytes
d4b85c0 |
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
import { isWhiteSpace } from './characterClasses.mjs';
/**
* Produces the value of a block string from its parsed raw value, similar to
* CoffeeScript's block string, Python's docstring trim or Ruby's strip_heredoc.
*
* This implements the GraphQL spec's BlockStringValue() static algorithm.
*
* @internal
*/
export function dedentBlockStringLines(lines) {
var _firstNonEmptyLine2;
let commonIndent = Number.MAX_SAFE_INTEGER;
let firstNonEmptyLine = null;
let lastNonEmptyLine = -1;
for (let i = 0; i < lines.length; ++i) {
var _firstNonEmptyLine;
const line = lines[i];
const indent = leadingWhitespace(line);
if (indent === line.length) {
continue; // skip empty lines
}
firstNonEmptyLine =
(_firstNonEmptyLine = firstNonEmptyLine) !== null &&
_firstNonEmptyLine !== void 0
? _firstNonEmptyLine
: i;
lastNonEmptyLine = i;
if (i !== 0 && indent < commonIndent) {
commonIndent = indent;
}
}
return lines // Remove common indentation from all lines but first.
.map((line, i) => (i === 0 ? line : line.slice(commonIndent))) // Remove leading and trailing blank lines.
.slice(
(_firstNonEmptyLine2 = firstNonEmptyLine) !== null &&
_firstNonEmptyLine2 !== void 0
? _firstNonEmptyLine2
: 0,
lastNonEmptyLine + 1,
);
}
function leadingWhitespace(str) {
let i = 0;
while (i < str.length && isWhiteSpace(str.charCodeAt(i))) {
++i;
}
return i;
}
/**
* @internal
*/
export function isPrintableAsBlockString(value) {
if (value === '') {
return true; // empty string is printable
}
let isEmptyLine = true;
let hasIndent = false;
let hasCommonIndent = true;
let seenNonEmptyLine = false;
for (let i = 0; i < value.length; ++i) {
switch (value.codePointAt(i)) {
case 0x0000:
case 0x0001:
case 0x0002:
case 0x0003:
case 0x0004:
case 0x0005:
case 0x0006:
case 0x0007:
case 0x0008:
case 0x000b:
case 0x000c:
case 0x000e:
case 0x000f:
return false;
// Has non-printable characters
case 0x000d:
// \r
return false;
// Has \r or \r\n which will be replaced as \n
case 10:
// \n
if (isEmptyLine && !seenNonEmptyLine) {
return false; // Has leading new line
}
seenNonEmptyLine = true;
isEmptyLine = true;
hasIndent = false;
break;
case 9: // \t
case 32:
// <space>
hasIndent || (hasIndent = isEmptyLine);
break;
default:
hasCommonIndent && (hasCommonIndent = hasIndent);
isEmptyLine = false;
}
}
if (isEmptyLine) {
return false; // Has trailing empty lines
}
if (hasCommonIndent && seenNonEmptyLine) {
return false; // Has internal indent
}
return true;
}
/**
* Print a block string in the indented block form by adding a leading and
* trailing blank line. However, if a block string starts with whitespace and is
* a single-line, adding a leading blank line would strip that whitespace.
*
* @internal
*/
export function printBlockString(value, options) {
const escapedValue = value.replace(/"""/g, '\\"""'); // Expand a block string's raw value into independent lines.
const lines = escapedValue.split(/\r\n|[\n\r]/g);
const isSingleLine = lines.length === 1; // If common indentation is found we can fix some of those cases by adding leading new line
const forceLeadingNewLine =
lines.length > 1 &&
lines
.slice(1)
.every((line) => line.length === 0 || isWhiteSpace(line.charCodeAt(0))); // Trailing triple quotes just looks confusing but doesn't force trailing new line
const hasTrailingTripleQuotes = escapedValue.endsWith('\\"""'); // Trailing quote (single or double) or slash forces trailing new line
const hasTrailingQuote = value.endsWith('"') && !hasTrailingTripleQuotes;
const hasTrailingSlash = value.endsWith('\\');
const forceTrailingNewline = hasTrailingQuote || hasTrailingSlash;
const printAsMultipleLines =
!(options !== null && options !== void 0 && options.minimize) && // add leading and trailing new lines only if it improves readability
(!isSingleLine ||
value.length > 70 ||
forceTrailingNewline ||
forceLeadingNewLine ||
hasTrailingTripleQuotes);
let result = ''; // Format a multi-line block quote to account for leading space.
const skipLeadingNewLine = isSingleLine && isWhiteSpace(value.charCodeAt(0));
if ((printAsMultipleLines && !skipLeadingNewLine) || forceLeadingNewLine) {
result += '\n';
}
result += escapedValue;
if (printAsMultipleLines || forceTrailingNewline) {
result += '\n';
}
return '"""' + result + '"""';
}
|