dotfiles/vscode/.vscode/extensions/randomfractalsinc.vscode-data-preview-2.3.0/node_modules/hjson/lib/hjson-stringify.js
Errol Sancaktar ff17c17e23 vscode
2024-06-14 09:31:58 -06:00

401 lines
14 KiB
JavaScript

/* Hjson http://hjson.org */
"use strict";
module.exports = function(data, opt) {
var common = require("./hjson-common");
var dsf = require("./hjson-dsf");
var plainToken = {
obj: [ '{', '}' ],
arr: [ '[', ']' ],
key: [ '', '' ],
qkey: [ '"', '"' ],
col: [ ':', '' ],
com: [ ',', '' ],
str: [ '', '' ],
qstr: [ '"', '"' ],
mstr: [ "'''", "'''" ],
num: [ '', '' ],
lit: [ '', '' ],
dsf: [ '', '' ],
esc: [ '\\', '' ],
uni: [ '\\u', '' ],
rem: [ '', '' ],
};
// options
var eol = common.EOL;
var indent = ' ';
var keepComments = false;
var bracesSameLine = false;
var quoteKeys = false;
var quoteStrings = false;
var condense = 0;
var multiline = 1; // std=1, no-tabs=2, off=0
var separator = ''; // comma separator
var dsfDef = null;
var sortProps = false;
var token = plainToken;
if (opt && typeof opt === 'object') {
opt.quotes = opt.quotes === 'always' ? 'strings' : opt.quotes; // legacy
if (opt.eol === '\n' || opt.eol === '\r\n') eol = opt.eol;
keepComments = opt.keepWsc;
condense = opt.condense || 0;
bracesSameLine = opt.bracesSameLine;
quoteKeys = opt.quotes === 'all' || opt.quotes === 'keys';
quoteStrings = opt.quotes === 'all' || opt.quotes === 'strings' || opt.separator === true;
if (quoteStrings || opt.multiline == 'off') multiline = 0;
else multiline = opt.multiline == 'no-tabs' ? 2 : 1;
separator = opt.separator === true ? token.com[0] : '';
dsfDef = opt.dsf;
sortProps = opt.sortProps;
// If the space parameter is a number, make an indent string containing that
// many spaces. If it is a string, it will be used as the indent string.
if (typeof opt.space === 'number') {
indent = new Array(opt.space + 1).join(' ');
} else if (typeof opt.space === 'string') {
indent = opt.space;
}
if (opt.colors === true) {
token = {
obj: [ '\x1b[37m{\x1b[0m', '\x1b[37m}\x1b[0m' ],
arr: [ '\x1b[37m[\x1b[0m', '\x1b[37m]\x1b[0m' ],
key: [ '\x1b[33m', '\x1b[0m' ],
qkey: [ '\x1b[33m"', '"\x1b[0m' ],
col: [ '\x1b[37m:\x1b[0m', '' ],
com: [ '\x1b[37m,\x1b[0m', '' ],
str: [ '\x1b[37;1m', '\x1b[0m' ],
qstr: [ '\x1b[37;1m"', '"\x1b[0m' ],
mstr: [ "\x1b[37;1m'''", "'''\x1b[0m" ],
num: [ '\x1b[36;1m', '\x1b[0m' ],
lit: [ '\x1b[36m', '\x1b[0m' ],
dsf: [ '\x1b[37m', '\x1b[0m' ],
esc: [ '\x1b[31m\\', '\x1b[0m' ],
uni: [ '\x1b[31m\\u', '\x1b[0m' ],
rem: [ '\x1b[35m', '\x1b[0m' ],
};
}
var i, ckeys=Object.keys(plainToken);
for (i = ckeys.length - 1; i >= 0; i--) {
var k = ckeys[i];
token[k].push(plainToken[k][0].length, plainToken[k][1].length);
}
}
//
var runDsf; // domain specific formats
var commonRange='\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff';
// needsEscape tests if the string can be written without escapes
var needsEscape = new RegExp('[\\\\\\"\x00-\x1f'+commonRange+']', 'g');
// needsQuotes tests if the string can be written as a quoteless string (like needsEscape but without \\ and \")
var needsQuotes = new RegExp('^\\s|^"|^\'|^#|^\\/\\*|^\\/\\/|^\\{|^\\}|^\\[|^\\]|^:|^,|\\s$|[\x00-\x1f'+commonRange+']', 'g');
// needsEscapeML tests if the string can be written as a multiline string (like needsEscape but without \n, \r, \\, \", \t unless multines is 'std')
var needsEscapeML = new RegExp('\'\'\'|^[\\s]+$|[\x00-'+(multiline === 2 ? '\x09' : '\x08')+'\x0b\x0c\x0e-\x1f'+commonRange+']', 'g');
// starts with a keyword and optionally is followed by a comment
var startsWithKeyword = new RegExp('^(true|false|null)\\s*((,|\\]|\\}|#|//|/\\*).*)?$');
var meta = {
// table of character substitutions
'\b': 'b',
'\t': 't',
'\n': 'n',
'\f': 'f',
'\r': 'r',
'"' : '"',
'\\': '\\'
};
var needsEscapeName = /[,\{\[\}\]\s:#"']|\/\/|\/\*/;
var gap = '';
//
var wrapLen = 0;
function wrap(tk, v) {
wrapLen += tk[0].length + tk[1].length - tk[2] - tk[3];
return tk[0] + v + tk[1];
}
function quoteReplace(string) {
return string.replace(needsEscape, function (a) {
var c = meta[a];
if (typeof c === 'string') return wrap(token.esc, c);
else return wrap(token.uni, ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
});
}
function quote(string, gap, hasComment, isRootObject) {
if (!string) return wrap(token.qstr, '');
needsQuotes.lastIndex = 0;
startsWithKeyword.lastIndex = 0;
// Check if we can insert this string without quotes
// see hjson syntax (must not parse as true, false, null or number)
if (quoteStrings || hasComment ||
needsQuotes.test(string) ||
common.tryParseNumber(string, true) !== undefined ||
startsWithKeyword.test(string)) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we first check if the string can be expressed in multiline
// format or we must replace the offending characters with safe escape
// sequences.
needsEscape.lastIndex = 0;
needsEscapeML.lastIndex = 0;
if (!needsEscape.test(string)) return wrap(token.qstr, string);
else if (!needsEscapeML.test(string) && !isRootObject && multiline) return mlString(string, gap);
else return wrap(token.qstr, quoteReplace(string));
} else {
// return without quotes
return wrap(token.str, string);
}
}
function mlString(string, gap) {
// wrap the string into the ''' (multiline) format
var i, a = string.replace(/\r/g, "").split('\n');
gap += indent;
if (a.length === 1) {
// The string contains only a single line. We still use the multiline
// format as it avoids escaping the \ character (e.g. when used in a
// regex).
return wrap(token.mstr, a[0]);
} else {
var res = eol + gap + token.mstr[0];
for (i = 0; i < a.length; i++) {
res += eol;
if (a[i]) res += gap + a[i];
}
return res + eol + gap + token.mstr[1];
}
}
function quoteKey(name) {
if (!name) return '""';
// Check if we can insert this key without quotes
if (quoteKeys || needsEscapeName.test(name)) {
needsEscape.lastIndex = 0;
return wrap(token.qkey, needsEscape.test(name) ? quoteReplace(name) : name);
} else {
// return without quotes
return wrap(token.key, name);
}
}
function str(value, hasComment, noIndent, isRootObject) {
// Produce a string from value.
function startsWithNL(str) { return str && str[str[0] === '\r' ? 1 : 0] === '\n'; }
function commentOnThisLine(str) { return str && !startsWithNL(str); }
function makeComment(str, prefix, trim) {
if (!str) return "";
str = common.forceComment(str);
var i, len = str.length;
for (i = 0; i < len && str[i] <= ' '; i++) {}
if (trim && i > 0) str = str.substr(i);
if (i < len) return prefix + wrap(token.rem, str);
else return str;
}
// What happens next depends on the value's type.
// check for DSF
var dsfValue = runDsf(value);
if (dsfValue !== undefined) return wrap(token.dsf, dsfValue);
switch (typeof value) {
case 'string':
return quote(value, gap, hasComment, isRootObject);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? wrap(token.num, String(value)) : wrap(token.lit, 'null');
case 'boolean':
return wrap(token.lit, String(value));
case 'object':
// If the type is 'object', we might be dealing with an object or an array or
// null.
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) return wrap(token.lit, 'null');
var comments; // whitespace & comments
if (keepComments) comments = common.getComment(value);
var isArray = Object.prototype.toString.apply(value) === '[object Array]';
// Make an array to hold the partial results of stringifying this object value.
var mind = gap;
gap += indent;
var eolMind = eol + mind;
var eolGap = eol + gap;
var prefix = noIndent || bracesSameLine ? '' : eolMind;
var partial = [];
var setsep;
// condense helpers:
var cpartial = condense ? [] : null;
var saveQuoteStrings = quoteStrings, saveMultiline = multiline;
var iseparator = separator ? '' : token.com[0];
var cwrapLen = 0;
var i, length; // loop
var k, v, vs; // key, value
var c, ca;
var res, cres;
if (isArray) {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
for (i = 0, length = value.length; i < length; i++) {
setsep = i < length -1;
if (comments) {
c = comments.a[i]||[];
ca = commentOnThisLine(c[1]);
partial.push(makeComment(c[0], "\n") + eolGap);
if (cpartial && (c[0] || c[1] || ca)) cpartial = null;
}
else partial.push(eolGap);
wrapLen = 0;
v = value[i];
partial.push(str(v, comments ? ca : false, true) + (setsep ? separator : ''));
if (cpartial) {
// prepare the condensed version
switch (typeof v) {
case 'string':
wrapLen = 0;
quoteStrings = true; multiline = 0;
cpartial.push(str(v, false, true) + (setsep ? token.com[0] : ''));
quoteStrings = saveQuoteStrings; multiline = saveMultiline;
break;
case 'object': if (v) { cpartial = null; break; } // falls through
default: cpartial.push(partial[partial.length - 1] + (setsep ? iseparator : '')); break;
}
if (setsep) wrapLen += token.com[0].length - token.com[2];
cwrapLen += wrapLen;
}
if (comments && c[1]) partial.push(makeComment(c[1], ca ? " " : "\n", ca));
}
if (length === 0) {
// when empty
if (comments && comments.e) partial.push(makeComment(comments.e[0], "\n") + eolMind);
}
else partial.push(eolMind);
// Join all of the elements together, separated with newline, and wrap them in
// brackets.
if (partial.length === 0) res = wrap(token.arr, '');
else {
res = prefix + wrap(token.arr, partial.join(''));
// try if the condensed version can fit (parent key name is not included)
if (cpartial) {
cres = cpartial.join(' ');
if (cres.length - cwrapLen <= condense) res = wrap(token.arr, cres);
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
var commentKeys = comments ? comments.o.slice() : [];
var objectKeys = [];
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k) && commentKeys.indexOf(k) < 0)
objectKeys.push(k);
}
if(sortProps) {
objectKeys.sort();
}
var keys = commentKeys.concat(objectKeys);
for (i = 0, length = keys.length; i < length; i++) {
setsep = i < length - 1;
k = keys[i];
if (comments) {
c = comments.c[k]||[];
ca = commentOnThisLine(c[1]);
partial.push(makeComment(c[0], "\n") + eolGap);
if (cpartial && (c[0] || c[1] || ca)) cpartial = null;
}
else partial.push(eolGap);
wrapLen = 0;
v = value[k];
vs = str(v, comments && ca);
partial.push(quoteKey(k) + token.col[0] + (startsWithNL(vs) ? '' : ' ') + vs + (setsep ? separator : ''));
if (comments && c[1]) partial.push(makeComment(c[1], ca ? " " : "\n", ca));
if (cpartial) {
// prepare the condensed version
switch (typeof v) {
case 'string':
wrapLen = 0;
quoteStrings = true; multiline = 0;
vs = str(v, false);
quoteStrings = saveQuoteStrings; multiline = saveMultiline;
cpartial.push(quoteKey(k) + token.col[0] + ' ' + vs + (setsep ? token.com[0] : ''));
break;
case 'object': if (v) { cpartial = null; break; } // falls through
default: cpartial.push(partial[partial.length - 1] + (setsep ? iseparator : '')); break;
}
wrapLen += token.col[0].length - token.col[2];
if (setsep) wrapLen += token.com[0].length - token.com[2];
cwrapLen += wrapLen;
}
}
if (length === 0) {
// when empty
if (comments && comments.e) partial.push(makeComment(comments.e[0], "\n") + eolMind);
}
else partial.push(eolMind);
// Join all of the member texts together, separated with newlines
if (partial.length === 0) {
res = wrap(token.obj, '');
} else {
// and wrap them in braces
res = prefix + wrap(token.obj, partial.join(''));
// try if the condensed version can fit
if (cpartial) {
cres = cpartial.join(' ');
if (cres.length - cwrapLen <= condense) res = wrap(token.obj, cres);
}
}
}
gap = mind;
return res;
}
}
runDsf = dsf.loadDsf(dsfDef, 'stringify');
var res = "";
var comments = keepComments ? comments = (common.getComment(data) || {}).r : null;
if (comments && comments[0]) res = comments[0] + '\n';
// get the result of stringifying the data.
res += str(data, null, true, true);
if (comments) res += comments[1]||"";
return res;
};