views:

186

answers:

3

Is here 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?

+3  A: 

JavaScript cant 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".

Jakob
+4  A: 

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.

Pointy
++, 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).
Evan Carroll
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](http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.1). :-P
Marcel Korpel
@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.
Pointy
@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
@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? :-)
Andy E
@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!)
Pointy
+1  A: 

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/

Andy E
Eeeeeuughhhhhh.
Tim Down
@Tim: I know :-)
Andy E
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."*
Tim Down
Doesn't work for me Firefox 3.5 `javascript:alert ( (function () { /*foo "" '" bar "' '' */ } ).toString() )`
Evan Carroll
@Evan: I'll admit, I didn't go as far as testing it in every browser :-)
Andy E
@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
@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.
Andy E
@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.
Tim Down