Javascript heredoc

后端 未结 14 1539
盖世英雄少女心
盖世英雄少女心 2020-12-02 12:55

I need something like heredoc in JavaScript. Do you have any ideas for this? I need cross-browser functionality.

I found this:

heredoc = \'\\
相关标签:
14条回答
  • 2020-12-02 13:24

    How about this:

    function MyHereDoc(){
    /*HERE
    <div>
       <p>
          This is written in the HEREDOC, notice the multilines :D.
       </p>
       <p>
          HERE
       </p>
       <p>
          And Here
       </p>
    </div>
    HERE*/
        var here = "HERE";
        var reobj = new RegExp("/\\*"+here+"\\n[\\s\\S]*?\\n"+here+"\\*/", "m");
        str = reobj.exec(MyHereDoc).toString();
        str = str.replace(new RegExp("/\\*"+here+"\\n",'m'),'').toString();
        return str.replace(new RegExp("\\n"+here+"\\*/",'m'),'').toString();
    }
    
    //Usage 
    document.write(MyHereDoc());
    

    Just replace "/*HERE" and "HERE*/" with word of choice.

    0 讨论(0)
  • 2020-12-02 13:26

    You can use Sweet.js Macros to add it like so, as created by Tim Disney in this post

    Note that this approach uses backticks as the string delimiters instead:

    let str = macro {
        case {_ $template } => {
            var temp = #{$template}[0];
            var tempString = temp.token.value.raw;
            letstx $newTemp = [makeValue(tempString, #{here})];
            return #{$newTemp}
        }
    }
    
    str `foo bar baz`
    
    0 讨论(0)
  • 2020-12-02 13:28

    I feel bad writing a separate answer for merely an extension to @NateFerrero's answer, but I don't feel editing his answer is appropriate either, so please upvote @NateFerrero if this answer was useful to you.

    tl;dr—For those who wish to use block comments inside their heredoc...

    I mainly needed Javascript heredocs to store a block of CSS, e.g.

    var css = heredoc(function() {/*
        /**
         * Nuke rounded corners.
         */
        body div {
            border-top-left-radius: 0 !important;
            border-top-right-radius: 0 !important;
            border-bottom-right-radius: 0 !important;
            border-bottom-left-radius: 0 !important;
        }
    */});
    

    As you can see however, I like to comment my CSS, and unfortunately (as hinted by the syntax highlighting) the first */ ends the overall comment, breaking the heredoc.


    For this specific purpose (CSS), my workaround was to add

    .replace(/(\/\*[\s\S]*?\*) \//g, '$1/')
    

    to the chain inside @NateFerrero's heredoc; in complete form:

    function heredoc (f) {
        return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1].replace(/(\/\*[\s\S]*?\*) \//g, '$1/');
    };
    

    and use it by adding a space between the * and / for "inner" block comments, like so:

    var css = heredoc(function() {/*
        /**
         * Nuke rounded corners.
         * /
        body div {
            border-top-left-radius: 0 !important;
            border-top-right-radius: 0 !important;
            border-bottom-right-radius: 0 !important;
            border-bottom-left-radius: 0 !important;
        }
    */});
    

    The replace simply finds /* ... * / and removes the space to make /* ... */, thereby preserving the heredoc until called.


    You can of course remove the comments altogether using

    .replace(/\/\*[\s\S]*?\* \//g, '')
    

    You can also support // comments if you add them to the chain:

    .replace(/^\s*\/\/.*$/mg, '')
    

    Also, you can do something other than the single space between * and /, like a -:

        /**
         * Nuke rounded corners.
         *-/
    

    if you just update the regex appropriately:

    .replace(/(\/\*[\s\S]*?\*)-\//g, '$1/')
                              ^
    

    Or maybe you'd like an arbitrary amount of whitespace instead of a single space?

    .replace(/(\/\*[\s\S]*?\*)\s+\//g, '$1/')
                              ^^^
    
    0 讨论(0)
  • 2020-12-02 13:29

    ES6 Template Strings has heredoc feature.

    You can declare strings enclosed by back-tick (` `) and can be expanded through multiple lines.

    var str = `This is my template string...
    and is working across lines`;
    

    You can also include expressions inside Template Strings. These are indicated by the Dollar sign and curly braces (${expression}).

    var js = "Java Script";
    var des = `Template strings can now be used in ${js} with lot of additional features`;
    
    console.log(des); //"Template strings can now be used in Java Script with lot of additional features"
    

    There are in fact more features such as Tagged Temple Strings and Raw Strings in it. Please find the documentation at

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings

    0 讨论(0)
  • 2020-12-02 13:33

    Depending on what flavour of JS/JS engine you're running (SpiderMonkey, AS3) you can simply write inline XML, into which you can place text on multiple lines, like heredoc:

    var xml = <xml>
        Here 
        is 
        some 
        multiline 
        text!
    </xml>
    
    console.log(xml.toXMLString())
    console.log(xml.toString()) // just gets the content
    
    0 讨论(0)
  • 2020-12-02 13:33
    // js heredoc - http://stackoverflow.com/a/32915549/466363
    // a function with comment with eval-able string, use it just like regular string
    
    function extractFuncCommentString(func,comments) {
      var matches = func.toString().match(/function\s*\(\)\s*\{\s*\/\*\!?\s*([\s\S]+?)\s*\*\/\s*\}/);
      if (!matches) return undefined;
      var str=matches[1];
    
       // i have made few flavors of comment removal add yours if you need something special, copy replacement lines from examples below, mix them
      if(comments===1 )
      {
       // keep comments, in order to keep comments  you need to convert /**/ to / * * / to be able to put them inside /**/ like /*    / * * /    */
       return (
        str
       .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */ 
       )
      }
      else if(comments===2)
      {
       // keep comments and replace singleline comment to multiline comment
       return (
        str
       .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */ 
       .replace(/\/\/(.*)/g,"/*$1*/")          //           change   //abc to  /*abc*/
       )
      }
      else if(comments===3)
      {
       // remove comments
       return (
          str
          .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
          .replace(/\/\/(.*)/g,"")             // match //abc
         )
      }
      else if(comments===4)
      {
       // remove comments and trim and replace new lines with escape codes
       return (
          str
          .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
          .replace(/\/\/(.*)/g,"")             // match //abc
          .trim() // after removing comments trim and:
          .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
         )
      }
      else if(comments===5)
      {
       // keep comments comments and replace strings, might not suit when there are spaces or comments before and after quotes 
       // no comments allowed before quotes of the string
       return (
          str
          .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */
          .replace(/\/\/(.*)/g,"/*$1*/")          //           change   //abc to  /*abc*/
          .trim() // trim space around quotes to not escape it and:
          .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
         )
      }
      else 
      return str
    }
    

    example

    var week=true,b=123;
    var q = eval(extractFuncCommentString(function(){/*!
    
    // this is a comment     
    
    
    'select 
    
    / * this
    is a multiline 
    comment * /
    
     a
    ,b  // this is a comment  
    ,c
    from `table`
    where b='+b+' and monthweek="'+(week?'w':'m')+'" 
    //+' where  a=124
    order by a asc
    '
    */},4));
    

    with cache: - make a simple template function, and save the function:(second time works fast)

    var myfunction_sql1;
    function myfunction(week,a){
    
    
        if(!myfunction_sql1) eval('myfunction_sql1=function(week,a){return ('+extractFuncCommentString(function(){/*!
    'select 
    
    / * this
    is a multiline 
    comment * /
    
     a
    ,b  // this is a comment  
    ,c
    from `table`
    where b='+b+' and monthweek="'+(week?'w':'m')+'" 
    //+' where  a=124
    order by a asc
    
    '*/},4)+')}');
        q=myfunction_sql1(week,a);
        console.log(q)
    }
    myfunction(true,1234)
    
    0 讨论(0)
提交回复
热议问题