code-prettify does not work with linear code (a single line)

Asked

Viewed 131 times

5

I’m using the Google library to format code: Google code-prettify

It works very well in almost every case, but as my text comes in a single string, it doesn’t work as well.

It works well for:

<ul>
  <li></li>
</ul>

And it doesn’t work for:

<ul><li></li></ul>

My example in Jsfiddler: https://jsfiddle.net/dorathoto/3qpwtcoy/8/

I tried to use several Javascript plugins to format, which in my case is XML standard and could not succeed in any.

  • Just a doubt: it seems that the problem is indentation. Why you cannot indent the code manually?

  • pq this code that comes linear, comes from a database, clearly if I could I would have already solved, but I do not have access to this inline code, so I need to find some plugin q make this indentation

  • Looking at the code in Jsfiddle, it’s always this tag <property> or can come any code?

  • @Sam, I believe so, but I can’t be sure (I believe 99% of the time yes), the best would be to format without knowing if it comes or not.

  • Blz. I just would know because I’m trying to make an indenter and not to waste time this information was necessary, because if it was just a tag it would be much easier. :)

1 answer

6


I made an indenter from scratch that worked on your Jsfiddle example and some other tests I did.

It works as follows:

Tag <xmp> initially empty and create soon after it a hidden div and put the linear code coming from the bank inside that div:

<div id="fonte" style="display: none;">código aqui</div>

The code will traverse all nodes within the div and assemble an array of objects tags = [], to take the element tag or the text node, which are two different things. You need to distinguish one thing from the other to be able to mount the indentation correctly.

It then traverses the array of objects creating a new HTML in the order of nodes with line breaks (\n) for each node, and play this new HTML inside the div, replacing what was there. The new HTML tags are all closed, but the browser automatically closes them all.

Then he takes the new HTML from the div and throws it into the <xmp>, but the last line will be linear with all automatic browser-generated shutdowns. That’s where it needs to be handled. Will take this line and break into array (last_str.match(/<.+?>/g)).

Then just go through this array by adding new lines to the <xmp> dynamically with document.createElement(), at the same time assigning the classes in the <li> sequentially (if not the component does not recognise) ranging from L0 to L9.

But for this to work, you need to use the callback of the component added at the end of the string URL &callback=iniciar (where iniciar is the callback function method. You can give the name you want instead of iniciar). This callback is called by the syntax:

window.exports = { 
   iniciar: function(){

    // código aqui

   }
}

The function is executed after the component has rendered the code.

Now let’s see it working:

document.addEventListener("DOMContentLoaded", function(){
   var xmp = document.getElementById("XMlHtml"),
   code = document.getElementById("fonte"),
   tags = [],
   tab = "   ", // espaços de tabulação
   tabr = 0;

   nos(code);
   function nos(node){
       for (var i = 0; i < node.childNodes.length; i++){
         var child = node.childNodes[i];
         no(child); nos(child);
       }
   }
   
   function no(e){
      var html = e.nodeType != 3 ? e.outerHTML.match(/^<.+?>/)[0] : null;
      tags.push({ no: html, txt: e.nodeValue });
   }

   var nhtml = '';
   for(var x=0; x<tags.length; x++){
      var no = tags[x].no;
      if(x != 0 && tags[x-1].no) tabr++;
      if(!no) no = tags[x].txt;
      nhtml += tab.repeat(tabr)+no+"\n";
   }
   
   code.innerHTML = nhtml;
   xmp.innerHTML = code.innerHTML;
   
   window.exports = { 
      iniciar: function(){
         var linhas = xmp.querySelectorAll("li"),
         last = linhas[linhas.length-1],
         classe = Number(last.className.replace("L", "")),
         last_str = last.textContent,
         ltags = last_str.match(/<.+?>/g);
         
         for(var x=0; x<ltags.length; x++){

            tabr--;

            if(x == 0){
               if(tabr == 0) tabr++;
               last.querySelector("span").textContent = tab.repeat(tabr)+ltags[0];
            }else{
               classe = classe < 9 ? classe+1 : 0;
               if(tabr < 0) tabr = 0;
               var nli = document.createElement("li");
               nli.setAttribute("class", "L"+classe);
               var span = document.createElement("span");
               span.setAttribute("class", "tag");
               var tabula = document.createTextNode(tab.repeat(tabr));
               span.appendChild(tabula);
               span.appendChild(document.createTextNode(ltags[x]));
               nli.appendChild(span);
               xmp.querySelector("ol").appendChild(nli);
            }
         }
      }
   }
});
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?callback=iniciar"></script>
<?prettify lang=xml?>
<xmp class="prettyprint linenums:4" id="XMlHtml"></xmp>
<div id="fonte" style="display: none;"><properties><property key="expression">from CodigoOcorrencia couch in {[left] =&gt; DefaultIfEmpty()}</property><property key="EventId"><structure type=""><property key="Id">20500</property><property key="Name">Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning</property></structure></property><property key="SourceContext">Microsoft.EntityFrameworkCore.Query</property><property key="Scope"><sequence><item>Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor</item></sequence></property><property key="SetorErro">MVC</property></properties></div>

I put all the code inside the event DOMContentLoaded for restrict the scope of variables and avoid possible conflicts with other variables you may be using in another code or script.

Note also that you can set tab width by variable var tab = " ", which in the case above, I placed with 3 spaces.

  • who knows, you know! who doesn’t know will in CTRL+C...thanks, I will test and already qualify

  • Give a test. If you give a bug we check.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.