JavaScript HERE-doc or other large-quoting mechanism?

12,798

Solution 1

Some people don't like this, so be prepared for scorn and derision, but one trick is to dump your "big block of stuff" into a <script language="text"> block:

<script id='blockOfStuff' language="text">
  Hi this is random stuff
  <h1>Including HTML markup</h1>
  And quotes too, or as one man said, "These are quotes, but
  'these' are quotes too."
</script>

John Resig has used that technique (or that abomination, if you prefer) for examples of his templating mechanism.

You can get at the contents with "innerText" or "innerHTML" as appropriate, or through the services of your favorite framework.

edit — note that via jQuery (contrary to what I said in a comment below) .text() does not work, though I think it should. Use .html() instead.

Solution 2

Not supported natively.

But since we're talking ways to make it work, here's one that (in my experience) does:

<script type="text/javascript">  

    var name = "Mud";

    var str = "\
        My name is " + name + "\
        not to be confused with Bill\
        or Jack or Pete or Dennis\
        my name is " + name + " and it's always been\
    ";

    alert("Les'n one: " + str);

</script>

Those back-slashes'll do the trick. Just make sure to backslash-escape any double quotes in your string since the whole block is quoted with them.

Note that this doesn't retain newlines, you have to insert them manually as "\n" prior to trailing slash on each line. On the other hand, any whitespace indentation at the beginning of each line will be included in the output.

Really this works best when you have to declare a long multiline string in a script (e.g. XML), not as good when you need to keep that string formatted exactly the way you define it.

Cheers

Solution 3

JavaScript can't do it but CoffeeScript, which is a thin layer on top of JavaScript, can.

Follow the link and scroll down to "Multiline Strings and Heredocs".

Solution 4

I remember seeing a clever solution a while ago that used multi-line comments in a function:

(function () {
   /*
      "This is an example of a multi-line string.  It's really just a mult-line
      comment, and it's wrapped in quote marks.  You might also notice the 
      apostrophe's ;-)"; 
   */
});

Note: that last apostrophe is intentionally incorrect ;-P

The trick is to call the function's toString() method and parse out the multi-line comment using a regular expression. Clever, but much like Pointy's suggestion, a bit of an abomination.

I didn't actually think the question to be looking for a seriously viable method for production uses -- my own fault for jumping to conclusions -- I'm not really sure why you wouldn't just escape the relevant string literal delimiters. As Tim Down pointed out in the comments below, ECMAScript 3rd edition defines toString() for functions as being implementation dependant.

For funsies, I decided to check out browser compatibility and this method is feasible in IE, Opera, Safari and Chrome but not Firefox, which does not include comments in the returned string. http://jsfiddle.net/2yvXG/

Solution 5

HereDoc For JavaScript

FuncToHereDoc ("delemiter", uncalled function with commented HEREDOC)

function FuncToHereDoc(here,str) {
    var reobj = new RegExp("/\\*"+here+"\\n[\\s\\S]*?\\n"+here+"\\*/", "m");
    str = reobj.exec(str).toString();
    str = str.replace(new RegExp("/\\*"+here+"\\n",'m'),'').toString();
    return str.replace(new RegExp("\\n"+here+"\\*/",'m'),'').toString();
}

Usage:

FuncToHereDoc("HERE", MyHereDoc);

function MyHereDoc(){
/*HERE
<p>
This is written ing the HEREDOC, notice the multilines :D.
</p>
<p>
HERE
</p>
<p>
And Here
</p>
HERE*/
}
Share:
12,798
Evan Carroll
Author by

Evan Carroll

#1 User for DBA.SE 2017. Available for contracting: 281.901.0011 PostgreSQL &amp; PostGIS / MySQL / SQL Server JavaScript, Typescript, Rx.js, Node.js, Angular Also: C / Perl / Python / Rust / x86 Assembly

Updated on June 03, 2022

Comments

  • Evan Carroll
    Evan Carroll almost 2 years

    Is there a convenient way to quote a large block of HTML that has both single and double quotes in JavaScript?

    Is there anything like a HERE-doc <<EOF, a multi-quote character """, or custom delimiters q{}?

    Any creative or inventive solutions to this problem?

  • Evan Carroll
    Evan Carroll almost 14 years
    ++, I'm amused. I'm not even that offended. Though in this case for SEO reasons I would prefer not to have the block of text in the html (because a dynamic action is brining it into play it isn't by default applicable to the page).
  • Tim Down
    Tim Down almost 14 years
    Seriously though, this is really brittle: how a function converts itself to a string is unspecified, and what works in current browsers may not work in future browsers. From the ECMAScript 3 spec: "15.3.4.2 Function.prototype.toString ( ). An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation string is implementation-dependent."
  • Evan Carroll
    Evan Carroll almost 14 years
    Doesn't work for me Firefox 3.5 javascript:alert ( (function () { /*foo "" '" bar "' '' */ } ).toString() )
  • Andy E
    Andy E almost 14 years
    @Evan: I'll admit, I didn't go as far as testing it in every browser :-)
  • Andy E
    Andy E almost 14 years
    @Tim: He asked for creative or inventive solutions, I think this qualifies at least for one of those ;-) In any case, I didn't intend the answer to be a serious suggestion for use in any production environment and probably should have mentioned that somewhere!
  • Andy E
    Andy E almost 14 years
    @Evan: btw, it works in Opera, Chrome, Safari and IE. I guess that doesn't help you much if you want it to be cross browser, though, sorry.
  • Marcel Korpel
    Marcel Korpel almost 14 years
    Unlike Andy's funny answer, does this work cross-browser? Oh, and as I said many times this day, the language attribute of <script> elements is deprecated. :-P
  • Tim Down
    Tim Down almost 14 years
    @Andy: Sure, it's creative. No criticism from me on that score :) At least you read the question fully, which is more than I managed.
  • Pointy
    Pointy almost 14 years
    @Marcel well I think it does; I haven't done a lot of testing. I kind-of assumed that if Mr. Resig was using it in blog posts etc. that it was probably fairly "safe." I too wonder about "language" esp. w.r.t. future HTML5 support.
  • Andy E
    Andy E almost 14 years
    @Marcel: I'm glad my answer amused you, I was smiling to myself whilst writing it. I think @Pointy has the only production-viable solution here, and I can't see why it wouldn't work in all browsers it certainly makes sense that it would, even with a totally bogus language or mime-type applied as long as neither were empty or an actual supported scripting language.
  • Andy E
    Andy E almost 14 years
    @Pointy: not to nit-pick, but "innerText()" and "innerHTML()"? Is there an "in" joke I'm not getting here or did someone promote those properties to functions? :-)
  • Pointy
    Pointy almost 14 years
    @Andy E well I think Firefox is pretty loosey-goosey with "innerHTML" and will hand back the contents of a <script>. If you call that in IE for <script> or <style> blocks you get a weird "Unknown exception" error, but I think "innerText()" works. I'm not super sure because I'd just call $('#scriptId').text()` :-) (Oh also they're not functions of course!! Sorry!)
  • LetMyPeopleCode
    LetMyPeopleCode about 12 years
    @MatrixFrog you can also do script type="text/html". OTOH trying to set up your text as an external file (script src='external.txt' type='text/html') doesn't seem to work.
  • Evan Carroll
    Evan Carroll over 11 years
    This just makes the assumption that the func.toString(); returns the source code. That was identified as being unsafe below
  • Evan Carroll
    Evan Carroll almost 11 years
    This just makes the assumption that the func.toString(); returns the source code. That was identified as being unsafe below
  • sebastien
    sebastien almost 11 years
    It says that it returns an implementation-dependent representation of the function, a FunctionDefinition, but where the whitespace is not sure. My wrap-up seems to take care of any whitespace issues, even if minimized.
  • Madbreaks
    Madbreaks over 10 years
    Op asked for a JS solution, not a DOM solution. What's the point of setting visibility:hidden; after you've already set display:none;?
  • Madbreaks
    Madbreaks about 9 years
    @EvanCarroll assuming vertical order of answers on SO is also unsafe ;)
  • yougotiger
    yougotiger over 8 years
    I used this solution as a good work around. This has allowed me to put lots of text that would have caused all kinds of JS heartache into my application without any problem.
  • aidan
    aidan over 8 years
    > Link-only answers can become invalid if the linked page changes. ...which is exactly what's happened. Here's a working url: coffeescript.org/#strings
  • bearvarine
    bearvarine over 6 years
    This is actually the most correct answer to the original question. Checked this as of IE 11.0.45 and it does work on that browser as well.