added basic pretty printing...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2025-12-23 18:37:09 +03:00
parent 37297cbe63
commit 51d0e0ddde

View File

@ -22,13 +22,26 @@ var RECURSIVE = '<RECURSIVE%>'
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// XXX add support for pretty printing... // XXX add support for pretty printing...
// to do this correctly, need to track, thread indent and to
// correctly offset nested json sections...
// XXX need to destinguish between map key and value in path... // XXX need to destinguish between map key and value in path...
var serialize = var serialize =
module.serialize = module.serialize =
function(obj, path=[], seen=new Map()){ function(obj, path=[], seen=new Map(), space, indent=0){
// args...
var args = [...arguments].slice(1)
if(typeof(args[0]) == 'number'){
space = args.shift() }
if(typeof(args[0]) == 'number'){
indent = args.shift() }
;[path, seen] = args
path ??= []
seen ??= new Map()
// recursive... // recursive...
var p = seen.get(obj) var p = seen.get(obj)
if(p != null){ if(p != null){
// NOTE: serialize(..) is always printed flat here, regardless of space/indent...
return RECURSIVE.replace('%', serialize(p)) } return RECURSIVE.replace('%', serialize(p)) }
// XXX functions... // XXX functions...
@ -38,15 +51,16 @@ function(obj, path=[], seen=new Map()){
if(obj === null){ if(obj === null){
return NULL } return NULL }
if(typeof(obj) != 'object'){ if(typeof(obj) != 'object'){
return obj === undefined ? return typeof(obj) == 'number'
UNDEFINED && isNaN(obj) ?
: isNaN(obj) ?
NAN NAN
: obj === undefined ?
UNDEFINED
: obj === Infinity ? : obj === Infinity ?
INFINITY INFINITY
: obj === -Infinity ? : obj === -Infinity ?
NEG_INFINITY NEG_INFINITY
: JSON.stringify(obj) } : JSON.stringify(obj, null, space) }
// objects... // objects...
seen.set(obj, path) seen.set(obj, path)
@ -61,29 +75,37 @@ function(obj, path=[], seen=new Map()){
for(var i=0; i < obj.length; i++){ for(var i=0; i < obj.length; i++){
elems.push( elems.push(
i in obj ? i in obj ?
serialize(obj[i], [...path, i], seen) serialize(obj[i], [...path, i], seen, space, indent+1)
: EMPTY) } : EMPTY) }
} else if(obj instanceof Map){ } else if(obj instanceof Map){
pre = 'Map(' pre = 'Map('
post = ')' post = ')'
elems = [serialize([...obj], path, seen)] elems = [serialize([...obj], path, seen, space, indent+1)]
} else if(obj instanceof Set){ } else if(obj instanceof Set){
pre = 'Set(' pre = 'Set('
post = ')' post = ')'
elems = [serialize([...obj], path, seen)] elems = [serialize([...obj], path, seen, space, indent+1)]
} else { } else {
pre = '{' pre = '{'
post = '}' post = '}'
for(var [k, v] of Object.entries(obj)){ for(var [k, v] of Object.entries(obj)){
elems.push(`${ elems.push(`${
JSON.stringify(k) JSON.stringify(k, null, space)
}:${ }:${ space != null ? ' ' : '' }${
serialize(v, [...path, k], seen) serialize(v, [...path, k], seen, space, indent+1).trimLeft()
}`) } } }`) } }
// handle indent...
if(space != null){
i = ' '.repeat(indent * space)
s = i + ' '.repeat(space)
pre = i + pre + '\n' + s
post = '\n' + i + post
join = join + '\n' + s }
return pre+ elems.join(join) +post } return pre+ elems.join(join) +post }
@ -94,7 +116,7 @@ function(obj, path=[], seen=new Map()){
var eJSON = var eJSON =
module.eJSON = { module.eJSON = {
chars: { chars: {
'"': 'string', "'": 'string', '"': 'string', "'": 'string', '`': 'string',
0: 'number', 1: 'number', 2: 'number', 3: 'number', 4: 'number', 0: 'number', 1: 'number', 2: 'number', 3: 'number', 4: 'number',
5: 'number', 6: 'number', 7: 'number', 8: 'number', 9: 'number', 5: 'number', 6: 'number', 7: 'number', 8: 'number', 9: 'number',
@ -180,22 +202,30 @@ module.eJSON = {
j++ } j++ }
return [ str.slice(i, j)*1, j, line ] }, return [ str.slice(i, j)*1, j, line ] },
// XXX count \\n // XXX count \\n
// XXX handle \\<match>
string: function(state, path, match, str, i, line){ string: function(state, path, match, str, i, line){
var j = i+1 var j = i+1
while(j < str.length while(j < str.length
&& str[j] != match){ && str[j] != match){
// XXX handle '\\n'.,.
if(str[j] == '\n'){ if(str[j] == '\n'){
line++ } line++ }
// skip escaped quotes...
if(str[j] == '\\'
&& j+1 < str.length
&& str[j+1] == match){
j++ }
j++ } j++ }
if(j == str.length if(j == str.length
&& str[j-1] != match){ && str[j-1] != match){
throw new SyntaxError('Unexpected end of input wile looking fot "'+ match +'".') } throw new SyntaxError('Unexpected end of input wile looking fot "'+ match +'".') }
return [ str.slice(i+1, j), j+1, line ] }, return [ str.slice(i+1, j), j+1, line ] },
identifier: function(state, path, match, str, i, line){ identifier: function(state, path, match, str, i, line){
// XXX if(!/[a-zA-Z_]/.test(str[i])){
}, throw new SyntaxError('Not an identifier: "'+ str[i] +'"') }
var j = i+1
while(j < str.length
&& /[a-zA-Z0-9_]/.test(str[j])){
j++ }
return [ str.slice(i, j), j, line ] },
// XXX method or func??? // XXX method or func???
// XXX interface??? // XXX interface???