Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript heredoc

Try ES6 String Template, you can do something like

var hereDoc = `
This
is
a
Multiple
Line
String
`.trim()


hereDoc == 'This\nis\na\nMultiple\nLine\nString'

=> true

You can use this great feature even in older browsers with TypeScript


No, unfortunately JavaScript does not support anything like heredoc.


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.


Building on Zv_oDD's answer, I created a similar function for easier reuse.

Warning: This is a non-standard feature of many JS interpreters, and will probably be removed at some point, but as I'm building a script to be only used in Chrome, I am using it! Do not ever rely on this for client-facing websites!

// Multiline Function String - Nate Ferrero - Public Domain
function heredoc(fn) {
  return fn.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
};

Use:

var txt = heredoc(function () {/*
A test of horrible
Multi-line strings!
*/});

Returns:

"A test of horrible
Multi-line strings!"

Notes:

  1. Text is trimmed on both ends, so any extra whitespace on either end is OK.

Edits:

2/2/2014 - changed to not mess with the Function prototype at all and use the name heredoc instead.

5/26/2017 - updated whitespace to reflect modern coding standards.


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

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


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/')
                          ^^^