Add pretty printing to yaz-json-parse
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 4 Sep 2012 10:18:24 +0000 (12:18 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 4 Sep 2012 10:18:24 +0000 (12:18 +0200)
Define new public function json_write_wrbuf_pretty.

doc/yaz-json-parse-man.xml
include/yaz/json.h
src/json.c
util/json-parse.c

index ca2bd21..3e84dc7 100644 (file)
@@ -52,7 +52,8 @@
     <term>-p</term>
     <listitem><para>
       Makes the JSON parser echo the JSON result string to standard output -
-      if parsing from stdin was successful.
+      if parsing from stdin was successful. If -p is given twice the
+      output is a multi line output with indentation (pretty print).
      </para></listitem>
    </varlistentry>
 
index e9c2385..c30f10c 100644 (file)
@@ -187,6 +187,13 @@ void json_parser_subst(json_parser_t p, int idx, struct json_node *n);
 YAZ_EXPORT
 void json_write_wrbuf(struct json_node *node, WRBUF result);
 
+/** \brief writes JSON tree with indentation (pretty print)
+    \param node JSON tree
+    \param result resulting JSON string buffer
+*/
+YAZ_EXPORT
+void json_write_wrbuf_pretty(struct json_node *node, WRBUF result);
+
 /** \brief writes JSON text to WRBUF with escaping
     \param b result
     \param str input string to be encoded
index 0f424af..d3cee68 100644 (file)
@@ -502,34 +502,76 @@ void wrbuf_json_puts(WRBUF b, const char *str)
     wrbuf_json_write(b, str, strlen(str));
 }
 
-void json_write_wrbuf(struct json_node *node, WRBUF result)
+static void json_indent(WRBUF result, int indent)
+{
+    size_t l = wrbuf_len(result);
+    if (l == 0 || wrbuf_buf(result)[l-1] == '\n')
+    {
+        int i;
+        for (i = 0; i < indent; i++)
+            wrbuf_putc(result, ' ');
+    }
+}
+
+static void json_write_wrbuf_r(struct json_node *node, WRBUF result, int indent)
 {
+    int sub_indent = -1;
+    if (indent >= 0)
+        sub_indent = indent + 1;
     switch (node->type)
     {
     case json_node_object:
+        json_indent(result, indent);
         wrbuf_puts(result, "{");
+        if (indent >= 0)
+        {
+            wrbuf_puts(result, "\n"); 
+            json_indent(result, sub_indent);
+        }
         if (node->u.link[0])
-            json_write_wrbuf(node->u.link[0], result);
+            json_write_wrbuf_r(node->u.link[0], result, sub_indent);
+        if (indent >= 0)
+        {
+            wrbuf_puts(result, "\n");
+            json_indent(result, indent);
+        }
         wrbuf_puts(result, "}");
         break;
     case json_node_array:
+        json_indent(result, indent);
         wrbuf_puts(result, "[");
+        if (indent >= 0)
+        {
+            wrbuf_puts(result, "\n");
+            json_indent(result, sub_indent);
+        }
         if (node->u.link[0])
-            json_write_wrbuf(node->u.link[0], result);
+        {
+            json_write_wrbuf_r(node->u.link[0], result, sub_indent);
+        }
+        if (indent >= 0)
+        {
+            wrbuf_puts(result, "\n");
+            json_indent(result, indent);
+        }
         wrbuf_puts(result, "]");
         break;
     case json_node_list:
-        json_write_wrbuf(node->u.link[0], result);
+        json_write_wrbuf_r(node->u.link[0], result, indent);
         if (node->u.link[1])
         {
             wrbuf_puts(result, ",");
-            json_write_wrbuf(node->u.link[1], result);
+            if (indent >= 0)
+                wrbuf_puts(result, " ");
+            json_write_wrbuf_r(node->u.link[1], result, indent);
         }
         break;
     case json_node_pair:
-        json_write_wrbuf(node->u.link[0], result);
+        json_write_wrbuf_r(node->u.link[0], result, indent);
         wrbuf_puts(result, ":");
-        json_write_wrbuf(node->u.link[1], result);
+        if (indent >= 0)
+            wrbuf_puts(result, " ");
+        json_write_wrbuf_r(node->u.link[1], result, indent);
         break;
     case json_node_string:
         wrbuf_puts(result, "\"");
@@ -551,6 +593,16 @@ void json_write_wrbuf(struct json_node *node, WRBUF result)
     }
 }
 
+void json_write_wrbuf_pretty(struct json_node *node, WRBUF result)
+{
+    json_write_wrbuf_r(node, result, 1);
+}
+
+void json_write_wrbuf(struct json_node *node, WRBUF result)
+{
+    json_write_wrbuf_r(node, result, -1);
+}
+
 static struct json_node **json_get_objectp(struct json_node *n,
                                            const char *name)
 {
index a9afe6b..903cb8b 100644 (file)
@@ -55,7 +55,7 @@ int main(int argc, char **argv)
         switch (ret)
         {
         case 'p':
-            print = 1;
+            print++;
             break;
         default:
             usage(argv[0]);
@@ -67,7 +67,10 @@ int main(int argc, char **argv)
     if (print)
     {
         WRBUF result = wrbuf_alloc();
-        json_write_wrbuf(n, result);
+        if (print > 1)
+            json_write_wrbuf_pretty(n, result);
+        else
+            json_write_wrbuf(n, result);
         puts(wrbuf_cstr(result));
         wrbuf_destroy(result);
     }