docs: function pprintJSON(formJson, opts, indentLevel, priorNodeStr) {
    opts = opts || {};
    opts.spaces = opts.spaces || 2;
    opts.lbracket = opts.lbracket || "[";
    opts.rbracket = opts.rbracket || "]";
    opts.separator = opts.separator || ", ";
    indentLevel = indentLevel || 0;
    var nl = opts.oneLine ? " " : "\n";
    var str = ""
  
    function indentToSpaces(indentLevel) {
      return(!opts.omitTop ? indentLevel * opts.spaces : (indentLevel - 1) * opts.spaces);
    }
  
    if(Array.isArray(formJson)) {
      var numSpaces = indentToSpaces(indentLevel);
      if(!(opts.omitTop && indentLevel === 0)) {
        // I added these last two checks below specifically for formatting html tags
        // (the length check might adversely effect formatting normal code not sure yet )
        if((priorNodeStr !== '"function"' && priorNodeStr !== 'function') &&
            formJson.length > 0 && formJson[0] !== "attr") {
          str += (priorNodeStr ? nl : "") // omit the unecessary *first* "\n"
          str += (priorNodeStr && numSpaces > 0 ? " ".repeat(numSpaces) : "")
        }
        str += opts.lbracket
      }
  
      if(formJson[0] === "object" || formJson[0] === "attr") {
        if(opts.attrsAsJson || opts.objectsAsJson) {
          // pretty print the key/value pairs of an object/attr as a js object:
          str += "{";
          for(var i=1; i<formJson.length;i+=2) {
            if(i === 1) { str += nl; }
            var propNameStr = pprintJSON(formJson[i], opts);
            propNameStr = ((propNameStr.indexOf("-") !== -1) ? '"' + propNameStr + '"' : propNameStr);
            str += (numSpaces+1 > 0 ? " ".repeat(indentToSpaces(indentLevel+1)) : "") +
                    propNameStr + ": " +
                    pprintJSON(formJson[i+1], opts, indentLevel + 2, formJson[i]) + (i+2 < formJson.length ? opts.separator : "") + nl;
          }
          str += "}";
        }
        else {
          // pretty print the key/value pairs of an object/attr as an s-expr list
          str += pprintJSON(formJson[0], opts) + opts.separator + nl;
          for(var i=1; i<formJson.length;i+=2) {
            str += (numSpaces+1 > 0 ? " ".repeat(indentToSpaces(indentLevel+1)) : "") +
                   pprintJSON(formJson[i], opts) + opts.separator +
                   pprintJSON(formJson[i+1], opts, indentLevel + 2, formJson[i]) + (i+2 < formJson.length ? opts.separator : "") + nl;
          }
        }
      }
      else {
        // pretty print the body of a normal list
        var priorNodeStr;
        formJson.forEach(function(node, i) {
          priorNodeStr = pprintJSON(node, opts, indentLevel + 1, priorNodeStr)
          str += priorNodeStr
          if(i < formJson.length - 1) {
            str += opts.separator
          }
        })
      }
      if(!(opts.omitTop && indentLevel === 0)) {
        str += opts.rbracket
      }
    }
    else if(formJson == null) {
      str += "null";
    }
    else if(typeof formJson === 'string' && !opts.bareSymbols) {
      // I had backslashed single quotes below -
      // but jsonlint rejected so I don't...
      str += ('"' + formJson.replace(/[\\"]/g, '\\$&') + '"')
    }
    else if(formJson.toString) {
      str += formJson.toString();
    }
    else {
      throw new Error('Unknown form type in pprintJSON: ' + formJson + ' (' + typeof formJson + ')');
    }
    return str
  }