Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 9 of 9
  1. #1
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,086
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Question Function display as string

    I almost have what I want here, but having some display problems.

    For all the String.prototype and Array.prototype functions, you can see the underlying code in the <textarea> section when selected.

    My idea would be to select desired functions, make them display as text.
    Then I would be able to copy and past into a section of the HTML
    or write to a .js extension text file with a copy/paste.

    I have a problem of complete display of two functions.
    See the output for the functions makeArray and Array.prototype.toDL.

    They do not display completely although they are not much different
    in construction from the earlier defined functions.
    Also the function only statements like $_ and makeArray(N) do not lend themselves to a simple copy/past without further editing.

    Any ideas as to why this is happening?
    Any suggestions to change the existing code?

    Code:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <title> Library Display </title>
    
    <script type="text/javascript">
    var funcList = [
       '$_',
       'Number.prototype.padDigit',
       'Number.prototype.rnd',
       'String.prototype.extractIDA',
       'String.prototype.extractIDN',
       'String.prototype.replaceAT',
       'String.prototype.replaceALL',
       'randOrd',
       'Array.prototype.toUL',
       'Array.prototype.toOL',
    
    // rest of list does NOT DISPLAY correctly but all WORK fine
       'makeArray',
       'Array.prototype.toDL',
    ];
    
    </script>
    
    <style type="text/css">
     li { list-style-type:none; }
    </style>
    
    </head>
    <body>
    <div id="divFuncList" style="width:50%"></div>
    
    <button onclick="clr()">Clear</button>
    <button onclick="displayFunctions('debug')">Display</button>
    <p>
    <textarea id="debug" cols="80" rows="15"></textarea><p>
    
    
    
    <script type="text/javascript">  // functions to be chosen for display
    function $_(IDS) {  // shorthand notation
      return document.getElementById(IDS); } 
    Number.prototype.padDigit = function() { // add leading 0 to # less than 10
      return (this < 10) ? '0'+this : this; }
    String.prototype.extractIDA = function() {  // extract alpha characters only
      return this.replace(/\d/g,''); }
    String.prototype.extractIDN = function() {  // extract numberic characters only
      return this.replace(/\D/g,''); }
    String.prototype.replaceAT = function () {  // replace characters at argument position (default=1)
      var rlen=(arguments[2]==null?1:arguments[2]);
      return this.substring(0,arguments[0])+arguments[1]+this.substring(arguments[0]+rlen); }
    String.prototype.replaceALL = function () {  // replace all arguments
      return this.split(arguments[0]).join(arguments[1]); }
    function randOrd(){  // shuffle array by arr.sort(randOrd());
      return (Math.round(Math.random())-0.5); } 
    Number.prototype.rnd = function() {  // create randome number 
      return Math.floor(Math.random()*this); }
    // Example usage:     var N = (100).rnd();
    Array.prototype.toUL=function(){  // create unordered list
      var b = '<ul class="autoUL"><li>';
          b += this.join(' <\/li><li>');
      return b+'<\/li><\/ul>'; }
    Array.prototype.toOL=function(){  // create ordered list
      var b = '<ol class="autoOL"><li>';
          b += this.join(' <\/li><li>');
      return b+'<\/li><\/ol>'; }
    
    function makeArray(N) { var arr = [];
      for (var i=0; i<N; i=i++) {
        arr.push(i); }
      return arr; }
    // Example usage:     var arr = makeArray(10)  // creates [0,1,2,3,4,5,6,7,8,9]
    Array.prototype.toDL=function(){  // create dl-dt-dd list
      var tarr;
      var b = '<dl class="autoDL">';
      while (this.length) {
        tarr = this.shift().split(',');
        b += '<dt>'+tarr[0]+'</dt>';
        for (var i=1; i<tarr.length; i++) { b += '<dd>'+tarr[i]+'</dd>'; }
      }
      return b+'<\/dl>'; }
    
    </script>
    
    
    
    <script type="text/javascript">  // following for this program only
    String.prototype.showFunction = function () {
      var tarr = this.split('{');
      var temp = tarr[1].split('}');
      return tarr[0]+'{'+temp[0]+'\n'+'}'+'\n'; }
    
    function clr() {
      var sel = document.getElementsByTagName('input');
      for (var i=0; i<sel.length; i++) { sel[i].checked = false; }
      $_('debug').value = ''; }
    //  $_('debug').innerHTML = ''; }
    
    function displayFunctions(IDS) {
      document.getElementById('debug').innerHTML = '';
      var sel = $_('divFuncList').getElementsByTagName('input');
      var str = '';
      for (var i=0; i<sel.length; i++) {
        if (sel[i].checked) { str += f2str(funcList[i])+'\n'; }
      } $_('debug').value+= str+'\n'; }
    //  } $_('debug').innerHTML += str; }
    
    function f2str(func) { return func + ' = ' + eval(func).toString().showFunction();  }
    function FuncList(info) { return '<li><label><input type="checkbox">'+info+'</label></li>'; }
    
    window.onload = function() {
      var str = '';
      for (var i=0; i<funcList.length; i++) { str += FuncList(funcList[i]); }
      $_('divFuncList').innerHTML = str;
    }
    </script>
    
    </body>
    </html>

  • #2
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,969
    Thanks
    56
    Thanked 557 Times in 554 Posts
    maybe I am misunderstanding the problem, but wouldn't it make more sense to use toString?

    Code:
    String.prototype.showFunction = function () {
      
      return this.toString(); }

  • #3
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,346
    Thanks
    11
    Thanked 589 Times in 570 Posts
    replace
    Code:
    temp[0]
    Code:
    with temp.slice(0,-1).join("}")
    might have to do the same for tarr, otherwise you just grab between the first braces, which if a function contains for/while/if/etc poses a problem.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #4
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,302
    Thanks
    28
    Thanked 276 Times in 270 Posts
    Quote Originally Posted by jmrker View Post
    Any ideas as to why this is happening?
    Any suggestions to change the existing code?
    You're splitting the function strings on the LEFT CURLY BRACKET character. The two relevant functions contain more than one of that character. That results in your split method-generated arrays having more than two elements. Since your script assumes that such arrays are exactly two elements in length, your script doesn't behave as expected.

    Quote Originally Posted by xelawho View Post
    maybe I am misunderstanding the problem, but wouldn't it make more sense to use toString?

    Code:
    String.prototype.showFunction = function () {
      
      return this.toString(); }
    It would. That, or one can eliminate the showFunction method and use of the eval method altogether:

    Code:
    function f2str(func) {
    	return document.getElementsByTagName("script").item(1).textContent.match(RegExp(func.replace(/\$/g, "\\$") + "(?:.|\\n)+?return.+?}"))[0];
    }
    Edit: The above code should be:

    Code:
    function f2str(func) {
    	var code = document.getElementsByTagName("script").item(1).textContent.match(RegExp(func.replace(/\$/g, "\\$") + "(?:.|\\n)+?return.+?}"))[0];
    	if (!/\./.test(func)) {
    		code = "function " + code;
    	}
    	return code;
    }
    Last edited by Arbitrator; 12-24-2013 at 10:25 PM. Reason: See the post.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #5
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,969
    Thanks
    56
    Thanked 557 Times in 554 Posts

    Thumbs up

    fwiw, my IE8 doesn't like textContent, but
    Code:
    	var code = document.getElementsByTagName("script").item(1).text.match(RegExp(func.replace(/\$/g, "\\$") + "(?:.|\\n)+?return.+?}"))[0];
    //etc
    seems to work, cross-browser

  • #6
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,086
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Question

    Thank you all for the suggested changes.

    I tried both function modifications for f2str() below
    [labeled as first and second attempts in the code section below]

    I must not have entered the code correctly as it gives me errors
    referring to the document.getElementsByTagName() line in both cases.
    Whereas before I was at least getting some display, now there is none shown.

    With only slight modifications from post #1,
    here is the latest version I am currently working with...
    Code:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <title> Library Display </title>
    
    <script type="text/javascript">
    var funcList = [
       '$_',
       'Number.prototype.padDigit',
       'Number.prototype.rnd',
       'String.prototype.extractIDA',
       'String.prototype.extractIDN',
       'String.prototype.replaceAT',
       'String.prototype.replaceALL',
       'randOrd',
       'Array.prototype.toUL',
       'Array.prototype.toOL',
    
    // rest of list does NOT DISPLAY correctly but all WORK fine
       'makeArray',
       'Array.prototype.toDL',
    ];
    
    </script>
    
    <style type="text/css">
     li { list-style-type:none; }
    </style>
    
    </head>
    <body>
    <div id="divFuncList" style="width:50%"></div>
    
    <button onclick="clr()">Clear</button>
    <button onclick="displayFunctions('debug')">Display</button>
    <p>
    <textarea id="debug" cols="80" rows="15"></textarea><p>
    
    
    
    <script type="text/javascript">  // functions to be chosen for display
    function $_(IDS) {  // shorthand notation
      return document.getElementById(IDS);
    } 
    Number.prototype.padDigit = function() { // add leading 0 to # less than 10
      return (this < 10) ? '0'+this : this;
    }
    String.prototype.extractIDA = function() {  // extract alpha characters only
      return this.replace(/\d/g,'');
    }
    String.prototype.extractIDN = function() {  // extract numberic characters only
      return this.replace(/\D/g,'');
    }
    String.prototype.replaceAT = function () {  // replace characters at argument position (default=1)
      var rlen=(arguments[2]==null?1:arguments[2]);
      return this.substring(0,arguments[0])+arguments[1]+this.substring(arguments[0]+rlen);
    }
    String.prototype.replaceALL = function () {  // replace all arguments
      return this.split(arguments[0]).join(arguments[1]);
    }
    function randOrd(){  // shuffle array by arr.sort(randOrd());
      return (Math.round(Math.random())-0.5);
    } 
    Number.prototype.rnd = function() {  // create randome number 
      return Math.floor(Math.random()*this);
    } // Example usage:     var N = (100).rnd();
    
    Array.prototype.toUL=function(){  // create unordered list
      var b = '<ul class="autoUL"><li>';
          b += this.join(' <\/li><li>');
      return b+'<\/li><\/ul>';
    }
    Array.prototype.toOL=function(){  // create ordered list
      var b = '<ol class="autoOL"><li>';
          b += this.join(' <\/li><li>');
      return b+'<\/li><\/ol>';
    }
    
    function makeArray(N) { var arr = [];
      for (var i=0; i<N; i=i++) { arr.push(i); }
      return arr;
    } // Example usage:     var arr = makeArray(10)  // creates [0,1,2,3,4,5,6,7,8,9]
    
    Array.prototype.toDL=function(){  // create dl-dt-dd list
      var tarr;
      var b = '<dl class="autoDL">';
      while (this.length) {
        tarr = this.shift().split(',');
        b += '<dt>'+tarr[0]+'</dt>';
        for (var i=1; i<tarr.length; i++) { b += '<dd>'+tarr[i]+'</dd>'; }
      } return b+'<\/dl>';
    }
    
    </script>
    
    
    
    <script type="text/javascript">  // following for this program only
    
    String.prototype.showFunction = function () { return this.toString(); }
    
    function clr() {
      var sel = document.getElementsByTagName('input');
      for (var i=0; i<sel.length; i++) { sel[i].checked = false; }
      $_('debug').value = '';
    }
    
    function displayFunctions(IDS) {
      document.getElementById('debug').innerHTML = '';
      var sel = $_('divFuncList').getElementsByTagName('input');
      var str = '';
      for (var i=0; i<sel.length; i++) {
        if (sel[i].checked) { str += f2str(funcList[i])+'\n'; }
      } $_('debug').value+= str+'\n';
    }
    
    /* First attempt
    function f2str(func) {
      return document.getElementsByTagName("script").item(1).textContent.match(RegExp(func.replace(/\$/g, "\\$") + "(?:.|\\n)+?return.+?}"))[0];
    }
    */
    
    /* Second attempt */
    function f2str(func) {
      var code = document.getElementsByTagName("script").item(1).text.match(RegExp(func.replace(/\$/g, "\\$") + "(?:.|\\n)+?return.+?}"))[0];
      if (!/\./.test(func)) { code = "function " + code; }
      return code;
    }
    
    
    function FuncList(info) { return '<li><label><input type="checkbox">'+info+'</label></li>'; }
    
    window.onload = function() {
      var str = '';
      for (var i=0; i<funcList.length; i++) { str += FuncList(funcList[i]); }
      $_('divFuncList').innerHTML = str;
    }
    </script>
    
    </body>
    </html>
    BTW: Merry Christmas to all!
    Last edited by jmrker; 12-25-2013 at 04:34 AM.

  • #7
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,302
    Thanks
    28
    Thanked 276 Times in 270 Posts
    Quote Originally Posted by jmrker View Post
    I must not have entered the code correctly as it gives me errors
    referring to the document.getElementsByTagName() line in both cases.
    Whereas before I was at least getting some display, now there is none shown.
    You changed your code formatting paradigm in the revised code by inserting a line-break before every RIGHT CURLY BRACKET in your reference functions. The regular expression character . matches everything except newlines, so that change was enough to cause the regular expression to no longer match and therefore the match method to return null. The following code contains a slightly revised regular expression that addresses the issue:

    Code:
    function f2str(func) {
     	var code = document.getElementsByTagName("script").item(1).textContent.match(RegExp(func.replace(/\$/g, "\\$") + "(?:.|\\n)+?return(?:.|\\n)+?}"))[0];
     	if (!/\./.test(func)) {
     		code = "function " + code;
     	}
     	return code;
    }
    A more flexible approach would be to add markers that demarcate the end of the code you want to match. This has the advantage of not relying on a pattern in your functional function code (such as the presence of a return statement) and allows you to also match post-function comments in your code (like the one at the end of makeArray). Example:

    Code:
    function f2str(func) {
     	var code = document.getElementsByTagName("script").item(1).textContent.match(RegExp("(" + func.replace(/\$/g, "\\$") + "(?:.|\\n)+?) // END_OF_FUNCTION"))[1];
     	if (!/\./.test(func)) {
     		code = "function " + code;
     	}
     	return code;
    }
    Code:
    <script type="text/javascript">  // functions to be chosen for display
    function $_(IDS) {  // shorthand notation
      return document.getElementById(IDS);
    } // END_OF_FUNCTION
    Number.prototype.padDigit = function() { // add leading 0 to # less than 10
      return (this < 10) ? '0'+this : this;
    } // END_OF_FUNCTION
    String.prototype.extractIDA = function() {  // extract alpha characters only
      return this.replace(/\d/g,'');
    } // END_OF_FUNCTION
    String.prototype.extractIDN = function() {  // extract numberic characters only
      return this.replace(/\D/g,'');
    } // END_OF_FUNCTION
    String.prototype.replaceAT = function () {  // replace characters at argument position (default=1)
      var rlen=(arguments[2]==null?1:arguments[2]);
      return this.substring(0,arguments[0])+arguments[1]+this.substring(arguments[0]+rlen);
    } // END_OF_FUNCTION
    String.prototype.replaceALL = function () {  // replace all arguments
      return this.split(arguments[0]).join(arguments[1]);
    } // END_OF_FUNCTION
    function randOrd(){  // shuffle array by arr.sort(randOrd());
      return (Math.round(Math.random())-0.5);
    } // END_OF_FUNCTION
    Number.prototype.rnd = function() {  // create randome number 
      return Math.floor(Math.random()*this);
    } // Example usage:     var N = (100).rnd(); // END_OF_FUNCTION
    
    Array.prototype.toUL=function(){  // create unordered list
      var b = '<ul class="autoUL"><li>';
          b += this.join(' <\/li><li>');
      return b+'<\/li><\/ul>';
    } // END_OF_FUNCTION
    Array.prototype.toOL=function(){  // create ordered list
      var b = '<ol class="autoOL"><li>';
          b += this.join(' <\/li><li>');
      return b+'<\/li><\/ol>';
    } // END_OF_FUNCTION
    
    function makeArray(N) { var arr = [];
      for (var i=0; i<N; i=i++) { arr.push(i); }
      return arr;
    } // Example usage:     var arr = makeArray(10)  // creates [0,1,2,3,4,5,6,7,8,9] // END_OF_FUNCTION
    
    Array.prototype.toDL=function(){  // create dl-dt-dd list
      var tarr;
      var b = '<dl class="autoDL">';
      while (this.length) {
        tarr = this.shift().split(',');
        b += '<dt>'+tarr[0]+'</dt>';
        for (var i=1; i<tarr.length; i++) { b += '<dd>'+tarr[i]+'</dd>'; }
      } return b+'<\/dl>';
    } // END_OF_FUNCTION
    
    </script>
    Quote Originally Posted by jmrker View Post
    BTW: Merry Christmas to all!
    Happy holidays!
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #8
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,086
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Lightbulb

    Thank you.

    I'll give your changes a test tomorrow as now it is late and I don't want Santa to skip me.

    Appreciate your quick response and suggested revisions.

  • #9
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,086
    Thanks
    38
    Thanked 498 Times in 492 Posts
    Thank you 'Arbitrator'. Just like opening a present on X-mas day.
    Seems to work fine for my needs.

    I'll clean it up a bit more (with comments) and put in into the "Post a Javascript" section.
    Perhaps others would then add snippets of code to the list with short examples.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •