Author Topic: xml pretty print  (Read 3033 times)

Offline RJP74

  • Registered User
  • Newbie
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
xml pretty print
« on: June 27, 2013, 06:33:38 pm »
I am evaluating editors and one of my needs is to be able to convert a one line xml string into a human readable form.
As I didn't find such a function I wrote a simple script to do this to see how easy the scripting is to use.
Access it as needed from the tools menu. I did not implement any integration with HippoEdit Menus.

here is the code - also in an attachment. :)

Code: Javascript
  1. #include "he_utils.js"  // generic helper functions
  2.  
  3. AddScriptInfo("0BE253F8-BE23-4B7C-928C-38293F18C9D2", "XMLPrettyPrint", "1.0.0.0", "XML Pretty Print", "HippoEDIT", "rjp", "none");
  4.  
  5. var sel = ActiveView.Selection;
  6. if ( sel.IsEmpty )
  7.         sel = new Range(0, 0, ActiveDocument.LineCount - 1, ActiveDocument.GetLineLength(ActiveDocument.LineCount - 1));
  8. var SelectedText = ActiveView.Document.GetText(sel);
  9.  
  10. var xmlNew = xmlPP(SelectedText);
  11. ActiveDocument.ReplaceText(sel, xmlNew, AddUndoActionType("XMLPrettyPrint"));
  12.  
  13. function xmlPP(xml) {
  14.         var reg = /(>)(<)(\/*)/g;
  15.         var xmlNew = xml.replace(reg, "$1\r\n$2$3"); // split into separate lines
  16.         var xmlArray = xmlNew.split("\r\n"); // split into an array.
  17.         var currentIndent = 0;
  18.         var formatted = "";
  19.  
  20.         for (var ixml = 0; ixml < xmlArray.length; ixml++) {
  21.                 var node = xmlArray[ixml];
  22.                 node = node.replace(/^\s+/g, ''); // left trim function in case already formatted
  23.                 node = node.replace(/\s+$/g, ''); // right trim function in case already formatted
  24.                 if (node.length > 0) {                    // eliminate blank lines
  25.                         var nextIndent = 0;
  26.                         var leftFill = "";
  27.  
  28.                         // work out how much to indent
  29.                         if (node.match(/.+<\/\w[^>]*>$/)) {}            // ignore these
  30.                         else if (node.match(/^<\/\w/)) {                        // terminator - decrease padding
  31.                                 if (currentIndent > 0) currentIndent -= 1;      }
  32.                         else if (node.match(/^<\w[^>]*[^\/]>.*$/))      // indent - next node not this.
  33.                                 nextIndent = 1;
  34.  
  35.                         //create the indent
  36.                         for (var i = 0; i < currentIndent; i++) {leftFill += "   ";} // uses 3 spaces per indent.
  37.                         formatted += leftFill + node + "\r\n";
  38.                         currentIndent += nextIndent;
  39.                 }
  40.         }
  41.         return formatted;
  42. }
« Last Edit: June 28, 2013, 12:05:49 am by alex »

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: xml pretty print
« Reply #1 on: June 28, 2013, 12:04:11 am »
Hi RJP74,

That is cool!

If you not aware, we offer free license for new script/plugin.
And because the script is valuable, you was able to create it even without API documentation ;) and you are actually the first who have created some new script (except of me) - you got a free license. Please send me a private message (or mail to supportbox at hippoedit) with name you want to use for registration and email, I send you a license key then.

Because as I said the function you added is actually rather useful, I have reworked your code a little bit and converted into a plug-in (you do not need AddScriptInfo if use only as tool script).
It now integrates much better into HE and replaces standard formatting commands (FormatSelection and FormatAll) if you call if in any XML inherited source file. Similar like JS beautifier plugin does.

Please review, if all is OK, I can publish it then in library, to be available from online repository.
Code: Javascript
  1. #include "he_utils.js" // generic helper functions
  2. #import "es5.js"
  3.  
  4. AddScriptInfo("0BE253F8-BE23-4B7C-928C-38293F18C9D2", "XMLPrettyPrint", "1.0.0.0", "XML Pretty Print", "rjp");
  5.  
  6. Application.onTextFormat = function(sel, bIndent) {
  7.         var syntax = this.GetStyleFromPos(sel.Start).Style.Syntax;
  8.         if (syntax.IsInheritedFrom("xml")) {
  9.                 if (sel.IsEmpty) sel = new Range(0, 0, ActiveDocument.LineCount - 1, ActiveDocument.GetLineLength(ActiveDocument.LineCount - 1));
  10.                 var text = ax2js(this.GetLines(sel, false)).join("");
  11.                 if (text != "")
  12.                         this.ActiveView.Position = this.ReplaceText(sel, xmlPP(text, this.LineBreak, mul(" ", this.IndentSize)), AddUndoActionType("XML Pretty Print"));               
  13.                 return true;
  14.         }
  15.         return false;
  16. }
  17.  
  18. function mul(str, num) {
  19.         return num ? Array(num + 1).join(str) : "";
  20. }
  21.  
  22. function xmlPP(xml, lb, defaultIndent) {
  23.         var xmlNew = xml.replace(/>\s*</g, ">\r\n<"); // split into separate lines
  24.         var xmlArray = xmlNew.split("\r\n"); // split into an array
  25.         var currentIndent = 0;
  26.         var formatted = "";
  27.  
  28.         for (var ixml = 0; ixml < xmlArray.length; ixml++) {
  29.                 var node = xmlArray[ixml];
  30.                 node = node.trim(); // trim leading/trailing spaces
  31.                 if (node.length > 0) { // eliminate blank lines
  32.                         var nextIndent = 0;                    
  33.  
  34.                         // work out how much to indent
  35.                         if (node.match(/.+<\/\w[^>]*>$/)) {} // ignore these
  36.                         else if (node.match(/^<\/\w/)) { // terminator - decrease padding
  37.                                 if (currentIndent > 0) currentIndent -= 1;
  38.                         } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) // indent - next node not this.
  39.                                 nextIndent = 1;
  40.  
  41.                         //create the indent, by use of document default spaces count per indent
  42.                         var leftFill = mul(defaultIndent, currentIndent);
  43.                         formatted += leftFill + node + lb;
  44.                         currentIndent += nextIndent;
  45.                 }
  46.         }
  47.         return formatted;
  48. }


Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: xml pretty print
« Reply #2 on: June 30, 2013, 01:40:49 am »
Once more thanks a lot -> script converted into plugin
http://wiki.hippoedit.com/plugins/xml-pretty-print

Offline Dokkie

  • Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: xml pretty print
« Reply #3 on: August 06, 2014, 10:16:14 pm »
I'm using HE V 1.5x. I've installed XMLprettyPrint today using the online facility. Installation appears to work.
However I get an error when attempting to format a single line XML.
Routine stops on this line:    Var Busetabs = (Tabmode != Etabmodetabstospaces);
Error message indicates the     Etabmodetabstospaces is undefined.

Offline RJP74

  • Registered User
  • Newbie
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: xml pretty print
« Reply #4 on: August 07, 2014, 09:13:52 am »
Hi,,

it seems the constants have been updated but not the xmlprettyprint module and associated documentation.
These syntax constants should now start ec... not e....
or in other words this page is out of date:
http://wiki.hippoedit.com/scripting/api/tab-modes

As a work around please edit your xmlPrettyPrint.hejs in c:\programFiles and change these two lines:
Code: [Select]
var bUseTabs = (TabMode != ecTabModeTabsToSpaces);
if ( bUseTabs && TabMode == ecTabModeAuto )
I will submit this as a bug and it should be corrected on the main server soon.

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: xml pretty print
« Reply #5 on: August 07, 2014, 10:49:27 am »
Hi Guys,

constants were changed by design to have consistence in naming of all constants exposed. This was done already long time ago, but after 1.50 release.
The simplest solution would be to install 1.51 beta from forum - it uses newest naming.

The workaround to keep scripts running in 1.50 and 1.51 is to use constants values instead of constants itself. I have done it in some plugins, but not everywhere.

I will try to release 1.51 soon to eliminate such problems.

BR, Alex.

Offline Dokkie

  • Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: xml pretty print
« Reply #6 on: August 08, 2014, 01:40:05 am »
Thank you,
Have installed v1.51 beta and ensured that variable indicated have changed. Pretty printing now works.

 

Related Topics

  Subject / Started by Replies Last post
8 Replies
3703 Views
Last post February 19, 2009, 05:00:48 pm
by alex
3 Replies
1785 Views
Last post February 19, 2009, 10:02:59 pm
by alex
3 Replies
1896 Views
Last post August 27, 2009, 07:03:36 pm
by alex