This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Reformat json in kate

Tags: None
(comma "," separated)
aseques
Registered Member
Posts
63
Karma
0

Reformat json in kate

Wed Jun 07, 2017 1:25 pm
Hello, I'd like to know if there's a way to reformat a json so it's human readable. I found a link posted on 2013 that speaks of a set of plugins (they told that have been integrated to kate), that allow with some other things "Pretty JSON: Pretty format of a JSON code selected".
Is that hidden somewhere? I'm on kate 16.12.3
lueck
Mentor
Posts
225
Karma
2
aseques
Registered Member
Posts
63
Karma
0

Re: Reformat json in kate

Thu Jun 08, 2017 9:55 am
Another alternative I thought of was to use the external tool, but it seem that it was removed from kate even before that the tools ( https://kate-editor.org/2011/08/09/main ... ls-plugin/ ), so it's neither a solution.
Any other ideas?
alex_091
Registered Member
Posts
9
Karma
0

Re: Reformat json in kate

Thu Apr 19, 2018 2:17 pm
I have the same problem, so I am using this post instead of creating a new one.
Is it possible that there is no way whatsoever to let kate indent a json???
I think it's a so important feature that it cannot be true, so maybe there is some way I was not able to find.
Otherwise, is there any other lightweight text editor of KDE that I could use that have this functionality?

Thanks
airdrik
Registered Member
Posts
1854
Karma
5
OS

Re: Reformat json in kate

Thu Apr 19, 2018 6:49 pm
I figured out to write my own kate script to do it.
The following is the relevant bits from that script (for Kate 4, I believe some parts probably need to be changed for Kate 5; not sure what though). Save it under the katepart config directory under script/commands as somename.js.
Of note, it uses tabs for indentation and formats objects of simple k:v pairs on a single line. The comment with test json is intended for testing the formatting so you can see how it formats different things. Feel free to modify/redistribute/whatever as you please.

Code: Select all
 /* kate-script
  * author: I don't care if you cite me here
  * license: whatever you want
  * revision: 0.1
  * kate-version: 4.14.13
  * functions: jsonFormat
  */

 require("range.js");
 
 function _getSelectedText()
 {
   var selection = view.selection();
    if (!selection.isValid()) {
        selection = document.documentRange();
    }
    return document.text(selection);
 }
 
 function _replaceSelectedText(newText)
 {
   var selection = view.selection();
    if (!selection.isValid()) {
        selection = document.documentRange();
    }

    view.clearSelection();

    document.editBegin();
    document.removeText(selection);
    document.insertText(selection.start, newText);
    document.editEnd();
 }

 function _removeWhitespace(text)
 {
   var inString = false;
   var text1 = '';
   for (var i = 0; i < text.length; i++)
   {
      var c = text[i];
      if(inString)
      {
         if(c == inString)
         {
            inString = false;
            text1 += c;
         }
         else if(c == '\\')
         {
            text1 += c + text[i+1];
            i++;
         }
         else
            text1 += c;
      }
      else
      {
         if(c == '\n' || c == ' ' || c == '\t' || c == '\r')
         {} // ignore
         else if (c == '"' || c == "'")
         {
            inString = c;
            text1 += c;
         }
         else
            text1 += c;
      }
   }
   return text1;
 }
 /*
 test json:
 {"hi": "ho", "object": {"a":"b{'a':'b','c':[]}", "c":"d"}, "array": [1,2,3,4], "emptyObj": {
      
      }, "emptyArray": [   ],
      "rows":[{"item1":112,"item2":3254,"data":{"hi":"world","hello":"all"}},{"item1":112,"item2":3254,"data":{"hi":"world","hello":"all"}}]}
  */
function jsonFormat()
{
   var text = _getSelectedText();
   text = _removeWhitespace(text);
   var text1 = '';
   var indent = '';
   var inString = false;
   for (var i = 0; i < text.length; i++)
   {
      var c = text[i];
      if(inString)
      {
         if(c == inString)
         {
            inString = false;
            text1 += c;
         }
         else if(c == '\\')
         {
            text1 += c + text[i+1];
            i++;
         }
         else
            text1 += c;
      }
      else
      {
         if (c == '{' || c == '[')
         {
            var rest = text.substring(i+1);
            var closeIndex = rest.indexOf(c == '{' ? '}' : ']');
            var nextOpenIndexC = rest.indexOf('{');
            var nextOpenIndexB = rest.indexOf('[');
            var nextOpenIndex = nextOpenIndexB == -1 ? nextOpenIndexC :
               nextOpenIndexC == -1 || nextOpenIndexB < nextOpenIndexC ? nextOpenIndexB :
               nextOpenIndexC;
            if(closeIndex == 0)
            {
               text1 += c + rest[0];
               i += 1;
            }
            else if(closeIndex < nextOpenIndex || nextOpenIndex == -1)
            {
               text1 += c + rest.substring(0, closeIndex + 1);
               i += closeIndex+1;
            }
            else
            {
               indent += '\t';
               text1 += c + '\n' + indent;
            }
         }
         else if (c == '}' || c == ']')
         {
            indent = indent.substring(0, indent.length-1);
            text1 += '\n' + indent + c;
         }
         else if (c == ',')
         {
            text1 += c + '\n' + indent;
         }
         else if (c == '"' || c == "'")
         {
            inString = c;
            text1 += c;
         }
         else
            text1 += c;
      }
   }
   _replaceSelectedText(text1);
}

function action(cmd) // set up the menu
{
   var a = new Object();
   a.icon = "";
   a.category = i18n("Mine"); // Set your own name for the menu category for this
   a.interactive = false;
   if (cmd == "jsonFormat")
   {
      a.text = i18n("Format Json");
      a.shortcut = "";
   }
   
   return a;
}

function help(cmd) // provide useful docs on the scripts
{
   if (cmd == "jsonFormat")
      return i18n("Formats the Json nicely");
}



airdrik, proud to be a member of KDE forums since 2008-Dec.
alex_091
Registered Member
Posts
9
Karma
0

Re: Reformat json in kate

Tue Apr 24, 2018 9:06 am
airdrik wrote:I figured out to write my own kate script to do it.
The following is the relevant bits from that script (for Kate 4, I believe some parts probably need to be changed for Kate 5; not sure what though). Save it under the katepart config directory under script/commands as somename.js.
Of note, it uses tabs for indentation and formats objects of simple k:v pairs on a single line. The comment with test json is intended for testing the formatting so you can see how it formats different things. Feel free to modify/redistribute/whatever as you please.

Code: Select all
 /* kate-script
  * author: I don't care if you cite me here
  * license: whatever you want
  * revision: 0.1
  * kate-version: 4.14.13
  * functions: jsonFormat
  */

 require("range.js");
 
 function _getSelectedText()
 {
   var selection = view.selection();
    if (!selection.isValid()) {
        selection = document.documentRange();
    }
    return document.text(selection);
 }
 
 function _replaceSelectedText(newText)
 {
   var selection = view.selection();
    if (!selection.isValid()) {
        selection = document.documentRange();
    }

    view.clearSelection();

    document.editBegin();
    document.removeText(selection);
    document.insertText(selection.start, newText);
    document.editEnd();
 }

 function _removeWhitespace(text)
 {
   var inString = false;
   var text1 = '';
   for (var i = 0; i < text.length; i++)
   {
      var c = text[i];
      if(inString)
      {
         if(c == inString)
         {
            inString = false;
            text1 += c;
         }
         else if(c == '\\')
         {
            text1 += c + text[i+1];
            i++;
         }
         else
            text1 += c;
      }
      else
      {
         if(c == '\n' || c == ' ' || c == '\t' || c == '\r')
         {} // ignore
         else if (c == '"' || c == "'")
         {
            inString = c;
            text1 += c;
         }
         else
            text1 += c;
      }
   }
   return text1;
 }
 /*
 test json:
 {"hi": "ho", "object": {"a":"b{'a':'b','c':[]}", "c":"d"}, "array": [1,2,3,4], "emptyObj": {
      
      }, "emptyArray": [   ],
      "rows":[{"item1":112,"item2":3254,"data":{"hi":"world","hello":"all"}},{"item1":112,"item2":3254,"data":{"hi":"world","hello":"all"}}]}
  */
function jsonFormat()
{
   var text = _getSelectedText();
   text = _removeWhitespace(text);
   var text1 = '';
   var indent = '';
   var inString = false;
   for (var i = 0; i < text.length; i++)
   {
      var c = text[i];
      if(inString)
      {
         if(c == inString)
         {
            inString = false;
            text1 += c;
         }
         else if(c == '\\')
         {
            text1 += c + text[i+1];
            i++;
         }
         else
            text1 += c;
      }
      else
      {
         if (c == '{' || c == '[')
         {
            var rest = text.substring(i+1);
            var closeIndex = rest.indexOf(c == '{' ? '}' : ']');
            var nextOpenIndexC = rest.indexOf('{');
            var nextOpenIndexB = rest.indexOf('[');
            var nextOpenIndex = nextOpenIndexB == -1 ? nextOpenIndexC :
               nextOpenIndexC == -1 || nextOpenIndexB < nextOpenIndexC ? nextOpenIndexB :
               nextOpenIndexC;
            if(closeIndex == 0)
            {
               text1 += c + rest[0];
               i += 1;
            }
            else if(closeIndex < nextOpenIndex || nextOpenIndex == -1)
            {
               text1 += c + rest.substring(0, closeIndex + 1);
               i += closeIndex+1;
            }
            else
            {
               indent += '\t';
               text1 += c + '\n' + indent;
            }
         }
         else if (c == '}' || c == ']')
         {
            indent = indent.substring(0, indent.length-1);
            text1 += '\n' + indent + c;
         }
         else if (c == ',')
         {
            text1 += c + '\n' + indent;
         }
         else if (c == '"' || c == "'")
         {
            inString = c;
            text1 += c;
         }
         else
            text1 += c;
      }
   }
   _replaceSelectedText(text1);
}

function action(cmd) // set up the menu
{
   var a = new Object();
   a.icon = "";
   a.category = i18n("Mine"); // Set your own name for the menu category for this
   a.interactive = false;
   if (cmd == "jsonFormat")
   {
      a.text = i18n("Format Json");
      a.shortcut = "";
   }
   
   return a;
}

function help(cmd) // provide useful docs on the scripts
{
   if (cmd == "jsonFormat")
      return i18n("Formats the Json nicely");
}



That looks nice! I don't know how to set up a kate script, but I can find out.
Why don't you publish it on github with a md documentation?
airdrik
Registered Member
Posts
1854
Karma
5
OS

Re: Reformat json in kate

Tue Apr 24, 2018 6:42 pm
Perhaps I'll get around to it. It has worked so far for what I've used it for, but would probably want to put more care into it when publishing for a general audience. (or if you want to do that, by all means go right ahead)

Some resources:
Blog post introducing Kate's scripting capabilities: https://kate-editor.org/2009/10/29/exte ... h-scripts/
Full documentation: https://docs.kde.org/stable5/en/applica ... pting.html

There are a couple of scripting plugins on opendesktop.org, though the pickings are thin. One in particular that stood out:
https://www.opendesktop.org/p/1126932/ - a large collection of scripted commands. The github repo is well-structured and includes a script for converting from kate 4 to 5.


airdrik, proud to be a member of KDE forums since 2008-Dec.
Slartibartfast
Registered Member
Posts
1
Karma
0

Re: Reformat json in kate

Wed May 22, 2019 11:50 am
Thanks so much for this. I updated the script to work with katepart5 / KDE Plasma 5

Code: Select all
var katescript = {
    "author": "airdrik https://forum.kde.org/viewtopic.php?f=25&t=140599",
    "license": "WTFPL",
    "revision": 0.1,
    "kate-version": "5.1",
    "functions": ["jsonFormat"],
    "actions": [
        {   "function": "jsonFormat",
            "name": "Format JSON",
            "category": "Formatting"
        }
    ]
}; // kate-script-header, must be at the start of the file without comments

 require("range.js");
 
 function _getSelectedText()
 {
   var selection = view.selection();
    if (!selection.isValid()) {
        selection = document.documentRange();
    }
    return document.text(selection);
 }
 
 function _replaceSelectedText(newText)
 {
   var selection = view.selection();
    if (!selection.isValid()) {
        selection = document.documentRange();
    }

    view.clearSelection();

    document.editBegin();
    document.removeText(selection);
    document.insertText(selection.start, newText);
    document.editEnd();
 }

 function _removeWhitespace(text)
 {
   var inString = false;
   var text1 = '';
   for (var i = 0; i < text.length; i++)
   {
      var c = text[i];
      if(inString)
      {
         if(c == inString)
         {
            inString = false;
            text1 += c;
         }
         else if(c == '\\')
         {
            text1 += c + text[i+1];
            i++;
         }
         else
            text1 += c;
      }
      else
      {
         if(c == '\n' || c == ' ' || c == '\t' || c == '\r')
         {} // ignore
         else if (c == '"' || c == "'")
         {
            inString = c;
            text1 += c;
         }
         else
            text1 += c;
      }
   }
   return text1;
 }
 /*
 test json:
 {"hi": "ho", "object": {"a":"b{'a':'b','c':[]}", "c":"d"}, "array": [1,2,3,4], "emptyObj": {
     
      }, "emptyArray": [   ],
      "rows":[{"item1":112,"item2":3254,"data":{"hi":"world","hello":"all"}},{"item1":112,"item2":3254,"data":{"hi":"world","hello":"all"}}]}
  */
function jsonFormat()
{
   var text = _getSelectedText();
   text = _removeWhitespace(text);
   var text1 = '';
   var indent = '';
   var inString = false;
   for (var i = 0; i < text.length; i++)
   {
      var c = text[i];
      if(inString)
      {
         if(c == inString)
         {
            inString = false;
            text1 += c;
         }
         else if(c == '\\')
         {
            text1 += c + text[i+1];
            i++;
         }
         else
            text1 += c;
      }
      else
      {
         if (c == '{' || c == '[')
         {
            var rest = text.substring(i+1);
            var closeIndex = rest.indexOf(c == '{' ? '}' : ']');
            var nextOpenIndexC = rest.indexOf('{');
            var nextOpenIndexB = rest.indexOf('[');
            var nextOpenIndex = nextOpenIndexB == -1 ? nextOpenIndexC :
               nextOpenIndexC == -1 || nextOpenIndexB < nextOpenIndexC ? nextOpenIndexB :
               nextOpenIndexC;
            if(closeIndex == 0)
            {
               text1 += c + rest[0];
               i += 1;
            }
            else if(closeIndex < nextOpenIndex || nextOpenIndex == -1)
            {
               text1 += c + rest.substring(0, closeIndex + 1);
               i += closeIndex+1;
            }
            else
            {
               indent += '\t';
               text1 += c + '\n' + indent;
            }
         }
         else if (c == '}' || c == ']')
         {
            indent = indent.substring(0, indent.length-1);
            text1 += '\n' + indent + c;
         }
         else if (c == ',')
         {
            text1 += c + '\n' + indent;
         }
         else if (c == '"' || c == "'")
         {
            inString = c;
            text1 += c;
         }
         else
            text1 += c;
      }
   }
   _replaceSelectedText(text1);
}


function help(cmd) // provide useful docs on the scripts
{
   if (cmd == "jsonFormat")
      return i18n("Formats the Json nicely");
}
User avatar
pvzh
Registered Member
Posts
24
Karma
1
OS

Re: Reformat json in kate

Fri Feb 07, 2020 7:20 pm
Very useful script, thank you for the idea! Formatting can be done more easily. Didn't notice any problems with my version:

Code: Select all
function jsonFormat() {
   var text = _getSelectedText();
   text = JSON.stringify(JSON.parse(text), null, 2);
   _replaceSelectedText(text);
}


The result for the test jSON:

Code: Select all
{
  "hi": "ho",
  "object": {
    "a": "b{'a':'b','c':[]}",
    "c": "d"
  },
  "array": [
    1,
    2,
    3,
    4
  ],
  "emptyObj": {},
  "emptyArray": [],
  "rows": [
    {
      "item1": 112,
      "item2": 3254,
      "data": {
        "hi": "world",
        "hello": "all"
      }
    },
    {
      "item1": 112,
      "item2": 3254,
      "data": {
        "hi": "world",
        "hello": "all"
      }
    }
  ]
}


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Sogou [Bot], Yahoo [Bot]