From 6904e21fc2f939df8cb06be0ce3407d79491b0a6 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 28 May 2021 07:26:36 -0700 Subject: json: indentation support for printing. * lib.c (out_json_rec): Save, establish and restore indentation when printing [ ] and { } notation. Enforce line breaks, and force a line break after the object if one occurred in the object. (out_json): Turn on indentation if it is off (but not if it is forced off). Restore after doing the object. --- lib.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/lib.c b/lib.c index b86cbf78..e1879df6 100644 --- a/lib.c +++ b/lib.c @@ -12642,31 +12642,51 @@ static void out_json_rec(val obj, val out, struct strm_ctx *ctx) { val sym = car(obj); if (sym == hash_lit_s) { + val save_indent; + int force_br = 0; val iter, next; put_char(chr('{'), out); + save_indent = inc_indent(out, zero); for (iter = cddr(obj), next = nil; iter; iter = next) { val pair = car(iter); next = cdr(iter); out_json_rec(car(pair), out, ctx); put_char(chr(':'), out); out_json_rec(cadr(pair), out, ctx); - if (next) + if (next) { put_char(chr(','), out); + if (width_check(out, nil)) + force_br = 1; + } } put_char(chr('}'), out); + if (force_br) + force_break(out); + if (save_indent) + set_indent(out, save_indent); return; } if (sym == vector_lit_s) { + val save_indent; + int force_br = 0; val iter, next; put_char(chr('['), out); + save_indent = inc_indent(out, zero); for (iter = cadr(obj), next = nil; iter; iter = next) { val elem = car(iter); next = cdr(iter); out_json_rec(elem, out, ctx); - if (next) + if (next) { put_char(chr(','), out); + if (width_check(out, nil)) + force_br = 1; + } } put_char(chr(']'), out); + if (force_br) + force_break(out); + if (save_indent) + set_indent(out, save_indent); return; } if (sym == sys_unquote_s) { @@ -12683,38 +12703,57 @@ static void out_json_rec(val obj, val out, struct strm_ctx *ctx) break; case VEC: { + val save_indent; + int force_br = 0; cnum len = c_num(length(obj), lit("print")); cnum i; put_char(chr('['), out); + save_indent = inc_indent(out, zero); for (i = 0; i < len; i++) { val elem = obj->v.vec[i]; out_json_rec(elem, out, ctx); - if (i < len - 1) + if (i < len - 1) { put_char(chr(','), out); + if (width_check(out, nil)) + force_br = 1; + } } put_char(chr(']'), out); - + if (force_br) + force_break(out); + if (save_indent) + set_indent(out, save_indent); return; } break; case COBJ: if (hashp(obj)) { + val save_indent; + int force_br = 0; val cell, next; struct hash_iter hi; us_hash_iter_init(&hi, obj); put_char(chr('{'), out); + save_indent = inc_indent(out, zero); for (next = nil, cell = hash_iter_next(&hi); cell; cell = next) { next = hash_iter_next(&hi); out_json_rec(car(cell), out, ctx); put_char(chr(':'), out); out_json_rec(cdr(cell), out, ctx); - if (next) + if (next) { put_char(chr(','), out); + if (width_check(out, nil)) + force_br = 1; + } } put_char(chr('}'), out); + if (force_br) + force_break(out); + if (save_indent) + set_indent(out, save_indent); return; } break; @@ -12736,9 +12775,12 @@ static void out_json_rec(val obj, val out, struct strm_ctx *ctx) static void out_json(val op, val obj, val out, struct strm_ctx *ctx) { + val save_mode = test_set_indent_mode(out, num_fast(indent_off), + num_fast(indent_data)); if (op == sys_qquote_s) put_char(chr('^'), out); out_json_rec(obj, out, ctx); + set_indent_mode(out, save_mode); } INLINE int circle_print_eligible(val obj) -- cgit v1.2.3