3397

I have the following code in Ruby. I want to convert this code into JavaScript. What is the equivalent code in JS?

text = <<"HERE"
This
Is
A
Multiline
String
HERE
Ryan M
  • 18,333
  • 31
  • 67
  • 74
Newy
  • 38,977
  • 9
  • 43
  • 59

43 Answers43

4413

Update:

ECMAScript 6 (ES6) introduces a new type of literal, namely template literals. They have many features, variable interpolation among others, but most importantly for this question, they can be multiline.

A template literal is delimited by backticks:

var html = `
  <div>
    <span>Some HTML here</span>
  </div>
`;

(Note: I'm not advocating to use HTML in strings)

Browser support is OK, but you can use transpilers to be more compatible.


Original ES5 answer:

Javascript doesn't have a here-document syntax. You can escape the literal newline, however, which comes close:

"foo \
bar"
Kelderic
  • 6,502
  • 8
  • 46
  • 85
Anonymous
  • 49,213
  • 1
  • 25
  • 19
  • 280
    Be warned: some browsers will insert newlines at the continuance, some will not. – staticsan Apr 30 '09 at 02:22
  • 45
    Visual Studio 2010 seems to be confused by this syntax as well. – jcollum Apr 17 '11 at 21:58
  • 63
    @Nate It is specified in [ECMA-262 5th Edition](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) section 7.8.4 and called *LineContinuation* : "A line terminator character cannot appear in a string literal, except as part of a *LineContinuation* to produce the empty character sequence. The correct way to cause a line terminator character to be part of the String value of a string literal is to use an escape sequence such as \n or \u000A." – some Sep 25 '12 at 02:28
  • 7
    So in summary it seems this is the most straightforward approach, compatible with all browsers at least back to IE6 (and probably earlier), as long as you don't care whether or not extra newlines might be added at the end of each line. Does anyone know which browsers/versions add newlines and which don't? – Matt Browne Feb 26 '13 at 18:35
  • 1
    Also: If you use [UglifyJS](https://github.com/mishoo/UglifyJS) for minification, it will put multiline strings created this way onto a single line (newline characters will not be added at the continuance). So as long as the browser you're developing in behaves the same way, then you can use this approach and get consistent results across browsers in the production version of your app (i.e. after minification). – Matt Browne Feb 26 '13 at 18:50
  • 23
    I don't see why you'd do this when browsers treat it inconsistently. "line1\n" + "line2" across multiple lines is readable enough and you're guaranteed consistent behavior. – SamStephens Mar 20 '13 at 20:14
  • 1
    `node 0.10.0`: works; requires explicit `\n` chars. to insert actual line breaks (per ECMAScript 5 spec). In other words: if you want every string-literal source-code line to correspond to a line in the resulting string, end lines with \n\ – mklement0 Mar 25 '13 at 14:50
  • 3
    This syntax is perfect for machines who will never accidentally put a space between the backslash and the newline. Everyone else will have to paste their code into SO's comment editor, to see the highlighted difference between `\ ` and \ – Zev Spitz Oct 11 '13 at 07:35
  • @some It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement – Ruan Mendes Sep 05 '14 at 19:38
  • @JuanMendes Yes? That is what the first sentence of the quote I did from the standard says. So what is your point? The seconds sentence tells in a formal way how to produce a string that has line terminators and that is split into multiple lines in the source code. I don't remember what Nate wrote in the now deleted comment, but I think it was something about this not being part of javascript. I refereed to the standard where it is defined and quoted the relevant part. – some Sep 06 '14 at 04:57
  • @some My point is that the question is asking for a multiline string, so this doesn't answer the question. Maybe the confusion is just because of the deleted comment that I never saw – Ruan Mendes Sep 06 '14 at 13:30
  • @JuanMendes And I haven't tried to answer the question because there was already plenty of other answers. Dresende has already commented "This is wrong, it's not multiline. It's only 1 line.", so I didn't need to repeat it. I only provided information about the LineContinuation in a comment, so I was a little surprised when you wrote your comment to me instead of Anonymous who was the one who answered the question! :) There is no support in ECMAScript 5.1 or earlier for the requested syntax. The closest thing is an escaped new line followed by a LineContinuation, but it is ugly, in my opinion. – some Sep 07 '14 at 05:10
  • 2
    This solution is not wrong - but it's obviously not the best. So sad it has such a high count here. Scroll down to read better solutions. – Zane Oct 26 '14 at 13:25
  • AFAIK, IE still does not support it – IcedDante Jul 27 '16 at 16:21
  • 23
    "Browser support is OK"... not supported by IE11 - not OK – Tom Andraszek May 25 '17 at 05:18
  • I have tested template literal on safari 7.1 Mavericks, I doesn't work. – Rishabh Agrahari Sep 14 '17 at 17:22
  • 2
    Browser support is **NOT** ok actually. IE gives "Invalid character" error for that character. I don't understand how it got so many upvotes... – yakya Dec 25 '17 at 10:56
  • It Fails for IE – César León Dec 29 '17 at 16:55
  • @sotn He probably meant "ok" as in "acceptable but not great". – Clonkex Mar 03 '22 at 22:46
  • This answer doesn't work for html code so i wonder why its even the accepted answer in 2022. I am using latest version of chrome. I ended up using this https://www.willpeavy.com/tools/minifier/ – Gandalf Oct 02 '22 at 16:38
  • How does this work with code indentation? Does it require stripping the whitespace? – Stevoisiak Nov 22 '22 at 16:58
  • related: https://stackoverflow.com/q/35803959 – djvg Jun 16 '23 at 18:38
1538

ES6 Update:

As the first answer mentions, with ES6/Babel, you can now create multi-line strings simply by using backticks:

const htmlString = `Say hello to 
multi-line
strings!`;

Interpolating variables is a popular new feature that comes with back-tick delimited strings:

const htmlString = `${user.name} liked your post about strings`;

This just transpiles down to concatenation:

user.name + ' liked your post about strings'

Original ES5 answer:

Google's JavaScript style guide recommends to use string concatenation instead of escaping newlines:

Do not do this:

var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';

The whitespace at the beginning of each line can't be safely stripped at compile time; whitespace after the slash will result in tricky errors; and while most script engines support this, it is not part of ECMAScript.

Use string concatenation instead:

var myString = 'A rather long string of English text, an error message ' +
               'actually that just keeps going and going -- an error ' +
               'message to make the Energizer bunny blush (right through ' +
               'those Schwarzenegger shades)! Where was I? Oh yes, ' +
               'you\'ve got an error and all the extraneous whitespace is ' +
               'just gravy.  Have a nice day.';
Devin Rhode
  • 23,026
  • 8
  • 58
  • 72
  • this doesn't work for me in canary chrome for windows even after enabling Experimental JavaScript – Inuart Nov 20 '12 at 01:09
  • 28
    I don't understand Google's recommendation. All browsers except extremely old ones support the backslash followed by newline approach, and will continue to do so in the future for backward compatibility. The only time you'd need to avoid it is if you needed to be sure that one and only one newline (or no newline) was added at the end of each line (see also my comment on the accepted answer). – Matt Browne Feb 26 '13 at 18:40
  • Those who want to try these stuffs, be sure to check [Chrome Canary][1] [1]: https://www.google.com/intl/en/chrome/browser/canary.html – Sazid Oct 31 '13 at 05:31
  • 8
    Note that template strings aren't supported in IE11, Firefox 31, Chrome 35, or Safari 7. See http://kangax.github.io/compat-table/es6/ – EricP May 24 '14 at 02:41
  • `In EcmaScript 6, you'll be able to use backticks for Template Strings, known in the spec as a NoSubstitutionTemplate. I think you can try this and other features by first downloading canary chrome and then turning on Enable Experimental JavaScript.` `This doesn't work for me in canary chrome for windows even after enabling Experimental JavaScript.` Agreed. I had tried it while writing a Chrome userscript and it didn’t work in any new or old version of Chromium or Chrome that I tried; they all threw `ILLEGAL TOKEN` errors. I guess as usual, Google wants to *insist* people do things their way. – Synetech Jun 01 '14 at 17:33
  • 46
    @MattBrowne Google's recommendation is already documented by them, in order of importance of reasons: (1) The whitespace at the beginning of each line [in the example, you don't want that whitespace in your string but it looks nicer in the code] (2) whitespace after the slash will result in tricky errors [if you end a line with `\ ` instead of `\\` it's hard to notice] and (3) while most script engines support this, it is not part of ECMAScript [i.e. why use nonstandard features?] Remember it's a style guide, which is about making code easy to read+maintain+debug: not just "it works" correct. – ShreevatsaR Jul 31 '16 at 20:29
  • 3
    amazing that after all these years string concatenation is still the best/safest/most compliant way to go with this. template literals (above answer) don't work in IE and escaping lines is just a mess that you're soon going to regret – Tiago Duarte Nov 11 '16 at 12:31
  • Note that if you have a very long string of string concatenations, it can trigger a stack overflow (https://github.com/cmdcolin/technical_oddities) – Colin D Dec 26 '18 at 18:32
  • 3
    Found out the hard way that older versions of Android do not support the backticks so if you have an Android app using the webView your backticks cause your app to not run! – Michael Fever Jun 26 '19 at 19:45
  • I found one interesting video explaining ES6 template literals here : https://www.youtube.com/watch?v=asRu9MPojFE – Milap Aug 25 '21 at 08:49
737

the pattern text = <<"HERE" This Is A Multiline String HERE is not available in js (I remember using it much in my good old Perl days).

To keep oversight with complex or long multiline strings I sometimes use an array pattern:

var myString = 
   ['<div id="someId">',
    'some content<br />',
    '<a href="#someRef">someRefTxt</a>',
    '</div>'
   ].join('\n');

or the pattern anonymous already showed (escape newline), which can be an ugly block in your code:

    var myString = 
       '<div id="someId"> \
some content<br /> \
<a href="#someRef">someRefTxt</a> \
</div>';

Here's another weird but working 'trick'1:

var myString = (function () {/*
   <div id="someId">
     some content<br />
     <a href="#someRef">someRefTxt</a>
    </div>        
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];

external edit: jsfiddle

ES20xx supports spanning strings over multiple lines using template strings:

let str = `This is a text
    with multiple lines.
    Escapes are interpreted,
    \n is a newline.`;
let str = String.raw`This is a text
    with multiple lines.
    Escapes are not interpreted,
    \n is not a newline.`;

1 Note: this will be lost after minifying/obfuscating your code

KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • 39
    Please don't use the array pattern. It will be slower than plain-old string concatenation in most cases. – BMiner Jul 17 '11 at 12:39
  • 2
    in *most* cases... did you also include the time required to allocate/build the array? Regardless... it's a bit more readable than joining arrays. – BMiner Jul 17 '11 at 21:58
  • 86
    The array pattern is more readable and the performance loss for an application is often negligible. As that perf test shows, even IE7 can do tens of thousands of operations per second. – Benjamin Atkin Aug 20 '11 at 08:16
  • 2
    @Kooilnc: some browsers can compile several literal concats into a single literal string, and in machine code, no less. The benchmark ought to have tried a large concat of string variables as well, which would be a more fair comparison against join(). – Roy Tinker Oct 11 '11 at 02:37
  • 2
    @RoyTinker: feel free to cook up a jsperf.com-test yourself, or fiddle around with my test ;) – KooiInc Oct 19 '11 at 10:10
  • 3
    This is my favorite way (it looks nice), and fast enough that I am willing to take a minor speed hit for code readability. – RobKohr Nov 22 '11 at 11:26
  • 2
    You could make a little function to do fast joins: function fastjoin(array){ out = ''; for(i in array){ out += i; } return out; } – Lodewijk Jan 08 '12 at 23:55
  • That's actually quite a bunch slower than those join's. Plus the join's are kind of the preferable way to do it. Joins it is. – Lodewijk Jan 09 '12 at 00:58
  • I like joins. Write the code that writes the code. Much better than concatenating many times. It's redundancy. – Rimian May 14 '12 at 04:42
  • 23
    +1 for an elegant alternative that not only works the same way in all browsers, but is also future-proof. – Pavel May 21 '12 at 06:06
  • Must encase with 'singles' and NOT "doubles" for me in Notepad++ – Cody Jan 10 '13 at 07:29
  • 3
    I personally just concatenate strings and let the performance issues get sorted out when the JS is minified and the strings are combined. – Michael Mior Jul 11 '13 at 14:04
  • 28
    @KooiInc Your tests start with the array already created, that skews the results. If you add the initialization of the array, straight concatenation is faster http://jsperf.com/string-concat-without-sringbuilder/7 See http://stackoverflow.com/questions/51185/are-javascript-strings-immutable-do-i-need-a-string-builder-in-javascript/4717855#4717855 As a trick for newlines, it may be OK, but it's definitely doing more work than it should – Ruan Mendes Aug 04 '13 at 08:02
  • 12
    @BMiner: 1) "Premature optimization is the root of all evil" - Donald Knuth, and 2) 'readability' is in the eye of the beholder –  Mar 25 '14 at 15:27
  • 2
    @bat When tested on Mac 10.9 with Firefox 32, the join was "100%" slower than concatenation, according to jsperf (972 million vs 1 million ops/second). – Chris Middleton Oct 02 '14 at 20:07
  • 4
    Be careful with the "comment in function" solution. Keep in mind that as soon as you will want to minimize your JS code, your comments will be stripped off. – Jerska Nov 17 '14 at 18:28
  • 1
    +1 for the amazing `regexp` trick. Works like a charm and I love it. I still am having an issue with escaping `/*` characters within `xml` strings, but its unnecessary. I'm only doing this for file based testing. Thanks man! – WebWanderer Jan 23 '15 at 16:56
  • Tested on Win 8.1 in Firefox & Chrome, join is 33% slower than concatenate. – nevelis May 07 '15 at 21:17
  • Tested on Win 8.1 in Chrome and Firefox, join is 99% slower for me. (1,997,886,948 vs 18,679,979 respectively 2,161,096,056 vs 2,145,283) – Florian Wendelborn May 27 '15 at 13:28
  • 2
    Unless this is deep inside a million nested loops and running on a potato, efficiency is probably irrelevant next to readability. +1 for the array – Wolfie Inu Oct 27 '15 at 08:35
  • There are >150 versions of the jsPerf test. I did not check even a large number of them. [Version 25](https://jsperf.com/join-concat/25) tests both string concatenation and `.join()` on both predefined and inline arrays. String concatenation is on the order of **500 to 1,000 times faster** than Array's `.join()`, based on testing in the current versions of Chrome and Firefox on 2017-02-19. String concatenation *can be* written with a similar level of readability. In my opinion, there is no effective benefit of using `.join()` for this, and a significant cost for just a "cool" style choice. – Makyen Feb 19 '17 at 23:27
  • Why would string concatenation be much faster than join? Is there some sort of magic in join's implementation? – AturSams Apr 12 '17 at 12:31
  • @zehelvion not anymore. This is a very old issue (2009), browsers are much better nowadays – KooiInc Apr 12 '17 at 13:06
  • @KooiInc, **What about concatenation within the multiline string?** – Pacerier Jul 09 '17 at 07:37
  • @Seblor why not? The sub header was not informative. – KooiInc Aug 24 '18 at 06:57
  • AFAIK, Template strings (or template literals) were not supported until ES2015 (ES6), so saying that any ES20XX version do seems wrong. – Seblor Aug 24 '18 at 07:14
  • @Seblor see http://exploringjs.com/es6/ch_template-literals.html, also http://exploringjs.com/es6/ch_faq.html#sec_es6-vs-es2015 – KooiInc Aug 24 '18 at 07:34
  • Oh I get my confusion there. The ECMAScript versions started beeing named "ES20XX" after ES6, I forgot about that. – Seblor Aug 24 '18 at 07:42
  • I like the array approach. Sure, it *may* be slower, but correctness and readability is, typically, more important. I could see a rationale to not use it on the browser, but it would be a good approach with server-side javascript. Plus, now we have backtick ("`") string templates that are even better. – luis.espinal Oct 22 '18 at 14:33
  • 1
    Example with regexp match contains variable in cooment expression /**/ . It can make problems if you decice to compress JS later. Many compressors remove comments! – Tomas Šivickas Nov 27 '19 at 11:14
  • Ignoring the naysayers moaning about the "performance hit" the array trick is actually a really elegant solution. Major kudos to you for posting this. Some genuine outside the box thinking here! – Hybrid web dev Jun 09 '20 at 05:31
  • Yeah guys seriously, the array trick is both elegant and functions. If you want you can say myString = ["Line 1", "Line 2"].join("\n"); or myString = ["Line 1", "Line 2"].join("\\n") and then just console.log(myString), copy paste the now formatted string into your code. My favorite has to be the comment in the function converted to a string one though! – cmarangu Aug 01 '22 at 02:13
370

You can have multiline strings in pure JavaScript.

This method is based on the serialization of functions, which is defined to be implementation-dependent. It does work in the most browsers (see below), but there's no guarantee that it will still work in the future, so do not rely on it.

Using the following function:

function hereDoc(f) {
  return f.toString().
      replace(/^[^\/]+\/\*!?/, '').
      replace(/\*\/[^\/]+$/, '');
}

You can have here-documents like this:

var tennysonQuote = hereDoc(function() {/*!
  Theirs not to make reply,
  Theirs not to reason why,
  Theirs but to do and die
*/});

The method has successfully been tested in the following browsers (not mentioned = not tested):

  • IE 4 - 10
  • Opera 9.50 - 12 (not in 9-)
  • Safari 4 - 6 (not in 3-)
  • Chrome 1 - 45
  • Firefox 17 - 21 (not in 16-)
  • Rekonq 0.7.0 - 0.8.0
  • Not supported in Konqueror 4.7.4

Be careful with your minifier, though. It tends to remove comments. For the YUI compressor, a comment starting with /*! (like the one I used) will be preserved.

I think a real solution would be to use CoffeeScript.

ES6 UPDATE: You could use backtick instead of creating a function with a comment and running toString on the comment. The regex would need to be updated to only strip spaces. You could also have a string prototype method for doing this:

let foo = `
  bar loves cake
  baz loves beer
  beer loves people
`.removeIndentation()

Someone should write this .removeIndentation string method... ;)

gpl
  • 1,380
  • 2
  • 8
  • 24
Jordão
  • 55,340
  • 13
  • 112
  • 144
  • 284
    What!? creating and decompiling a Function to hack a multiline comment into being a multiline string? Now *that's* ugly. – fforw Jun 17 '11 at 15:49
  • 5
    http://jsfiddle.net/fqpwf/ works in Chrome 13 and IE8/9, but not FF6. I hate to say it, but I like it, and if it could be an intentional feature of each browser (so that it wouldn't disappear), I'd use it. – Jason Kleban Sep 09 '11 at 21:36
  • I had hope for function.[toSource](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/toSource)() for FF but no. – Jason Kleban Sep 09 '11 at 22:03
  • 3
    @uosɐſ: for it to be intentional, it'd have to be in the spec; or so widespread used, that browser makers wouldn't want to remove this "accidental" feature. Thanks for the experiments though... Try some coffeescript. – Jordão Sep 10 '11 at 02:37
  • @BrockAdams: thanks for the information; this is exactly why this approach is an _unreliable_ hack. – Jordão Dec 25 '11 at 00:16
  • 2
    a.toString().substring(15, a.toString().length-4) also works, and doesn't need to scan the entire string (although it most likely will and the counting makes it another scan anyway. Oh wel.) – Lodewijk Jan 08 '12 at 23:53
  • 3
    Extremely handy. I'm using it for (Jasmine) unit tests, but avoiding it for production code. – Jason Jul 13 '12 at 05:23
  • 1
    @Jason: I don't know if that's a good idea, even for testing. Your test environment might also evolve and drop this _accidental_ feature. Please reconsider. This post is for entertainment purposes only.... – Jordão Jul 13 '12 at 13:22
  • 1
    My Heredoc works in my Fx and Chrome on Mac: [DEMO](http://jsfiddle.net/mplungjan/pMSc8/) – mplungjan Feb 17 '13 at 09:54
  • You just made it easy for me to add huge html blocks to my QUnit tests! I am now creating a StaticStrings object in my test class that holds a bunch of these strings. – Rhyous Feb 24 '14 at 16:51
  • Its was failed when I have literal inside the comments. – Korjavin Ivan Apr 16 '14 at 16:42
  • Syntax become ugly when you need to pass variables inside long multi-line text. Or you have to replace strings several times. – Eugene Mala Oct 24 '15 at 14:56
  • Even simpler `hereDoc(() => {/*! Theirs not to make reply, Theirs not to reason why, Theirs but to do and die */});` – Prakash GPz Nov 26 '16 at 10:41
  • @fforw, It's pretty neat actually, if only its implementation independent. – Pacerier Jun 17 '17 at 17:59
  • You don't need regex for this: `function hereDoc(f) { var fs = ''+f; return fs.substring(fs.indexOf("/*!")+3, fs.lastIndexOf("*/")); }` – James Wilkins Oct 15 '17 at 18:24
  • 2
    @JamesWilkins: indeed you don't. In fact, you don't even should use this solution in the first place – Jordão Oct 15 '17 at 23:31
  • I know, just making the answer a bit more complete for new people finding it. ;) – James Wilkins Oct 16 '17 at 02:37
  • Have yet to encounter an instance where this doesn't work properly in back end applications, from node 0.0.10 to 10.0.0 so far. Albeit not using regex, using `let start = f.toString().indexOf('/*')+2` to `let end = f.indexOf('*/')-start` and substring operation. It's also great since you can precompile text blocks from `required` files into cache on app launch with this approach. – hajikelist May 23 '19 at 19:02
  • 1
    @hajikelist: you should really be using [template strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) by now (node >= 4.0.0). – Jordão May 24 '19 at 10:11
  • 1
    @Jordão - well - of course I'm using templates strings wherever possible. There is a case for using these with custom mysql scripts [for prep statements of course] containing tons of backticks. I still don't think this approach is as bad as some of these overly dramatic responses make it out to be. This has literally worked everywhere I've had to try it for the last 7 or 8 years. Cheers. – hajikelist May 26 '19 at 19:06
  • @Jordão On the matter of the `.removeIndentation()` method how about `.replace(/^\s+(\S.*)/gm, "$1")` – foobored Apr 22 '20 at 03:29
  • I'm not endorsing this solution, but just to be pedantic, the quantifiers in the regexp should be '*', not '+'. It's a moot point because current browsers will always return more than one character outside of the commented string (since the value of `f.toString()` includes the curly brackets etc.), but still. If the comment DID start at the beginning of the string for some reason, these patterns would fail unnecessarily. The art of regexps is to specify /exactly/ what you mean, so this kind of imprecision is unsightly. [adjusts monocle] – bobtato Mar 26 '22 at 18:23
  • How does one escape the `*/` comment delimiter if it were to occur inside of the string? – Bergi Jul 31 '22 at 19:59
223

You can do this...

var string = 'This is\n' +
'a multiline\n' + 
'string';
Ray Toal
  • 86,166
  • 18
  • 182
  • 232
alex
  • 479,566
  • 201
  • 878
  • 984
  • First example is great and simple. Much better than the \ approach as I'm not sure how browser's would handle the backslash as an escape character and as a multi-line character. – Matt K Nov 03 '11 at 19:13
  • The CDATA code (E4X) is [obsolete and will soon stop working even in Firefox](https://developer.mozilla.org/en-US/docs/E4X). – Brock Adams Nov 22 '12 at 12:16
  • [e4x.js](https://github.com/eligrey/e4x.js/blob/master/e4x.js) would be the good future-proof solution – Paul Sweatte Jan 19 '13 at 02:54
186

I came up with this very jimmy rigged method of a multi lined string. Since converting a function into a string also returns any comments inside the function you can use the comments as your string using a multilined comment /**/. You just have to trim off the ends and you have your string.

var myString = function(){/*
    This is some
    awesome multi-lined
    string using a comment 
    inside a function 
    returned as a string.
    Enjoy the jimmy rigged code.
*/}.toString().slice(14,-3)

alert(myString)
Luke
  • 1,974
  • 1
  • 11
  • 5
94

I'm surprised I didn't see this, because it works everywhere I've tested it and is very useful for e.g. templates:

<script type="bogus" id="multi">
    My
    multiline
    string
</script>
<script>
    alert($('#multi').html());
</script>

Does anybody know of an environment where there is HTML but it doesn't work?

Peter V. Mørch
  • 13,830
  • 8
  • 69
  • 103
60

I solved this by outputting a div, making it hidden, and calling the div id by jQuery when I needed it.

e.g.

<div id="UniqueID" style="display:none;">
     Strings
     On
     Multiple
     Lines
     Here
</div>

Then when I need to get the string, I just use the following jQuery:

$('#UniqueID').html();

Which returns my text on multiple lines. If I call

alert($('#UniqueID').html());

I get:

enter image description here

XXN
  • 128
  • 9
Tom Beech
  • 2,289
  • 1
  • 21
  • 25
  • 4
    Thanks for this! It's the only answer I've found that solves my problem, which involves unknown strings that may contain any combination of single and double quotes being directly inserted into the code with no opportunity for pre-encoding. (it's coming from a templating language that creates the JS -- still from a trusted source and not a form submission, so it's not TOTALLY demented). – octern Jun 23 '13 at 17:19
  • This was the only method that actually worked for me to create a multi-line javascript string variable from a Java String. – beginner_ Aug 06 '13 at 12:06
  • this gets the work done for me, although it doesnot solve multiline string values assignment to javascript variables – Venkat Sep 23 '13 at 16:24
  • 4
    What if the string is HTML? – Dan Dascalescu Jan 24 '14 at 08:39
  • 4
    $('#UniqueID').content() – mplungjan Jan 24 '14 at 09:28
  • @TomBeech, Interesting idea, but **there's a limitation**: you can't put a variable within it. The only stopgap is to do ugly search-and-replace. – Pacerier Jul 09 '17 at 09:25
  • Just be warned that search engines do still index content in hidden DIVs. – Gavin Jul 17 '17 at 16:21
  • @Gavin, Are u sure about that? Especially that we have already set it to `display:none`? – Pacerier Aug 06 '17 at 22:19
  • 1
    @Pacerier Everything I've read, from Google as well as other sites, says that nowadays Google does index `display:none` content, most likely due to the popularity of JavaScript-styled front-ends. (For example, an FAQ page with hide/show functionality.) You need to be careful though, because Google says they can punish you if the hidden content appears to be designed to artificially inflate your SEO rankings. – Gavin Aug 08 '17 at 13:12
34

There are multiple ways to achieve this

1. Slash concatenation

  var MultiLine=  '1\
    2\
    3\
    4\
    5\
    6\
    7\
    8\
    9';

2. regular concatenation

var MultiLine = '1'
+'2'
+'3'
+'4'
+'5';

3. Array Join concatenation

var MultiLine = [
'1',
'2',
'3',
'4',
'5'
].join('');

Performance wise, Slash concatenation (first one) is the fastest.

Refer this test case for more details regarding the performance

Update:

With the ES2015, we can take advantage of its Template strings feature. With it, we just need to use back-ticks for creating multi line strings

Example:

 `<h1>{{title}}</h1>
  <h2>{{hero.name}} details!</h2>
  <div><label>id: </label>{{hero.id}}</div>
  <div><label>name: </label>{{hero.name}}</div>
  `
Vignesh Subramanian
  • 7,161
  • 14
  • 87
  • 150
32

Using script tags:

  • add a <script>...</script> block containing your multiline text into head tag;
  • get your multiline text as is... (watch out for text encoding: UTF-8, ASCII)

    <script>
    
        // pure javascript
        var text = document.getElementById("mySoapMessage").innerHTML ;
    
        // using JQuery's document ready for safety
        $(document).ready(function() {
    
            var text = $("#mySoapMessage").html(); 
    
        });
    
    </script>
    
    <script id="mySoapMessage" type="text/plain">
    
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="...">
           <soapenv:Header/>
           <soapenv:Body>
              <typ:getConvocadosElement>
                 ...
              </typ:getConvocadosElement>
           </soapenv:Body>
        </soapenv:Envelope>
    
        <!-- this comment will be present on your string -->
        //uh-oh, javascript comments...  SOAP request will fail 
    
    
    </script>
    
jpfreire
  • 1,268
  • 16
  • 23
  • I think this strategy is clean & far underused. jsrender uses this. – xdhmoore Jan 09 '15 at 15:57
  • I'm using this with innerText iso innerHTML, But how do I make sure that the whitespaces are preserved ? – David Nouls Jul 16 '15 at 08:53
  • Also ajax queries in case you are using them. You can try to change your headers `xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");` I don't remember having other problems than mistyping comments in JS. Spaces where no problems. – jpfreire Oct 28 '15 at 05:40
27

A simple way to print multiline strings in JavaScript is by using template literals(template strings) denoted by backticks (` `). you can also use variables inside a template string-like (` name is ${value} `)

You can also

const value = `multiline`
const text = `This is a
${value}
string in js`;
console.log(text);
itsankitbhusal
  • 431
  • 4
  • 7
25

I like this syntax and indendation:

string = 'my long string...\n'
       + 'continue here\n'
       + 'and here.';

(but actually can't be considered as multiline string)

semente
  • 7,265
  • 3
  • 34
  • 35
  • 3
    I use this, except I put the '+' at the end of the preceding line, to make it clear the statement is continued on the next line. Your way does line up the indents more evenly though. – Sean Oct 04 '12 at 08:54
  • @Sean i use this too, and i still prefer put the '+' at the beginning of each new line added, and the final ';' on a new line, cuz i found it more 'correct'. – AgelessEssence Nov 14 '13 at 05:06
  • 7
    putting the + at the beginning allows one to comment out that line without having to edit other lines when its the first/last line of the sequence. – moliad Dec 12 '13 at 15:38
  • 3
    I prefer the + at the front too as visually I do not need to scan to the end of the line to know the next one is a continuation. – Daniel Sokolowski May 07 '14 at 15:40
21

Downvoters: This code is supplied for information only.

This has been tested in Fx 19 and Chrome 24 on Mac

DEMO

var new_comment; /*<<<EOF 
    <li class="photobooth-comment">
       <span class="username">
          <a href="#">You</a>:
       </span>
       <span class="comment-text">
          $text
       </span> 
       @<span class="comment-time">
          2d
       </span> ago
    </li>
EOF*/
// note the script tag here is hardcoded as the FIRST tag 
new_comment=document.currentScript.innerHTML.split("EOF")[1]; 
document.querySelector("ul").innerHTML=new_comment.replace('$text','This is a dynamically created text');
<ul></ul>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 17
    That's horrific. +1. And you can use [document.currentScript](https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript) instead of getElement... – Orwellophile May 27 '15 at 10:00
  • currentScript ? In what browsers? My answer is more than 2 years old :) – mplungjan May 27 '15 at 10:10
  • But it was a unique answer. I'm actually writing a polyfill now, but mainly because jsfiddle loads your script inline. I want to code the *interpolation –– (abandoning #{} because ES7 decrees ${this.var}. – Orwellophile May 27 '15 at 10:51
  • [jsfiddle](http://jsfiddle.net/orwellophile/hjmv3jrz/3/) Implemented with interpolation of local variables, unlimited unique HEREDOCs, method adaptable for `function(){/*!` style HEREDOC aswell. Abbreviated usage: `HEREDOC="EOF";/*!EOF ... EOF*/ currentScript().split(HEREDOC)[2]; ` – Orwellophile May 27 '15 at 11:44
  • 1
    Undefined "you" in chrome for osx – mplungjan May 27 '15 at 16:46
  • 1
    [jsfiddle-fixed](http://jsfiddle.net/orwellophile/hjmv3jrz/5/) - I must have had "you" defined globally in my console. Works now (chrome/osx). The nice thing about adding the comment to a var is that you're not in a function context, [jsfiddle-function-heredoc](http://jsfiddle.net/orwellophile/hna15vLw/2/) although the function thing would be cool for class methods. might be better to pass it a replace { this: that } object anyways. fun to push something crazy to the limit anyway :) – Orwellophile Jun 01 '15 at 16:44
  • 1
    Forget the haters. This is the only correct answer bar ES6. All the other answers require concatenation, computation of some sort, or escaping. This is actually pretty cool and I'm going to use it as a way to add documentation to a game I'm working on as a hobby. As long as this trick isn't used for anything that could invoke a bug (I can see how someone would go "Semicolon, derp. Lets put the comment on the next line." and then it breaks your code.) But, is that really a big deal in my hobby game? No, and I can use the cool trick for something useful. Great answer. – Thomas Dignan Jul 27 '15 at 21:10
  • Still shows `undefined` throughout the text for me - Chrome/OSX. – Steve Bennett Aug 17 '15 at 00:19
  • I will look when I get to an iMac end of this week – mplungjan Aug 17 '15 at 03:30
  • 2
    I've never been brave enough to use this technique in production code, but where I DO use it a lot is in unit testing, where often it's easiest to dump the value of some structure as a (quite long) string and compare it to what it 'should' be. – Ben McIntyre Feb 03 '16 at 00:00
19

There's this library that makes it beautiful:

https://github.com/sindresorhus/multiline

Before

var str = '' +
'<!doctype html>' +
'<html>' +
'   <body>' +
'       <h1>❤ unicorns</h1>' +
'   </body>' +
'</html>' +
'';

After

var str = multiline(function(){/*
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/});
Shahar 'Dawn' Or
  • 2,713
  • 1
  • 26
  • 38
  • 1
    This support in `nodejs`, using in browser must becareful. – Huei Tan May 05 '14 at 08:52
  • 3
    @HueiTan Docs state it also works in the browser. Which makes sense - it's just `Function.prototype.String()`. – mikemaccana Jul 13 '14 at 19:14
  • ya but it said "While it does work fine in the browser, it's mainly intended for use in Node.js. Use at your own risk.While it does work fine in the browser, it's mainly intended for use in Node.js. Use at your own risk." (Just becareful XD) – Huei Tan Jul 14 '14 at 09:37
  • @HueiTanYep I read that part. But Function.prototype.toString() is pretty stable and well known. – mikemaccana Jul 14 '14 at 10:52
  • 1
    Best answer for me because it at least achieves multiline without all the rubbish in the middle(The rubbish at the beginning and ends I can deal with). – Damien Golding Aug 27 '14 at 06:25
17

Found a lot of over engineered answers here. The two best answers in my opinion were:

1:

 let str = `Multiline string.
            foo.
            bar.`

which eventually logs:

Multiline string.
           foo.
           bar.  

2:

let str = `Multiline string.
foo.
bar.`

That logs it correctly but it's ugly in the script file if str is nested inside functions / objects etc...:

Multiline string.
foo.
bar.

My really simple answer with regex which logs the str correctly:

let str = `Multiline string.
           foo.
           bar.`.replace(/\n +/g, '\n');

Please note that it is not the perfect solution but it works if you are sure that after the new line (\n) at least one space will come (+ means at least one occurrence). It also will work with * (zero or more).

You can be more explicit and use {n,} which means at least n occurrences.

Niv
  • 523
  • 1
  • 8
  • 19
12

The equivalent in javascript is:

var text = `
This
Is
A
Multiline
String
`;

Here's the specification. See browser support at the bottom of this page. Here are some examples too.

Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
11

This works in IE, Safari, Chrome and Firefox:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<div class="crazy_idea" thorn_in_my_side='<table  border="0">
                        <tr>
                            <td ><span class="mlayouttablecellsdynamic">PACKAGE price $65.00</span></td>
                        </tr>
                    </table>'></div>
<script type="text/javascript">
    alert($(".crazy_idea").attr("thorn_in_my_side"));
</script>
  • 8
    Just think about it. Do you think it's valid? Don't you think it can cause display problems? – Sk8erPeter Feb 24 '12 at 01:55
  • 6
    Why the downvotes? This is a creative answer, if not very practical! – dotancohen Feb 29 '12 at 02:32
  • 3
    no, it's not. One should rather use templates: $.tmpl() (http://api.jquery.com/tmpl/), or EJS (http://embeddedjs.com/getting_started.html), etc. One reason for downvotes is that it's really far from a valid code and using this can cause huge display problems. – Sk8erPeter Mar 24 '12 at 00:07
  • I hope no one ever uses this answer in practice, but it's a neat idea – DCShannon Mar 13 '15 at 23:48
  • Edge case when you have `'` within the html. in that case you may have to use html entities `'`. – borracciaBlu Dec 18 '20 at 04:25
11

to sum up, I have tried 2 approaches listed here in user javascript programming (Opera 11.01):

So I recommend the working approach for Opera user JS users. Unlike what the author was saying:

It doesn't work on firefox or opera; only on IE, chrome and safari.

It DOES work in Opera 11. At least in user JS scripts. Too bad I can't comment on individual answers or upvote the answer, I'd do it immediately. If possible, someone with higher privileges please do it for me.

Community
  • 1
  • 1
Tyler
  • 349
  • 4
  • 11
  • This is my first actual comment. I have gained the upvote privilege 2 days ago so so I immediately upvoted the one answer I mentioned above. Thank you to anyone who did upvote my feeble attempt to help. – Tyler Jul 24 '11 at 12:34
  • Thanks to everyone who actually upvoted this answer: I have now enough privileges to post normal comments! So thanks again. – Tyler Aug 31 '12 at 02:41
11

Exact

Ruby produce: "This\nIs\nA\nMultiline\nString\n" - below JS produce exact same string

text = `This
Is
A
Multiline
String
`

// TEST
console.log(JSON.stringify(text));
console.log(text);

This is improvement to Lonnie Best answer because new-line characters in his answer are not exactly the same positions as in ruby output

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • text is string why json.stringify? – FlatLander Jul 12 '20 at 11:20
  • 1
    @FlatLander this is only for test - to see where are exactly new-line characters `\n` (to compare with ruby output (working example linked in answer) ) - this is improvement of Lonnie answer because new-line characters in his answer are not exactly the same positions as in ruby output – Kamil Kiełczewski Jul 12 '20 at 20:51
10

My extension to https://stackoverflow.com/a/15558082/80404. It expects comment in a form /*! any multiline comment */ where symbol ! is used to prevent removing by minification (at least for YUI compressor)

Function.prototype.extractComment = function() {
    var startComment = "/*!";
    var endComment = "*/";
    var str = this.toString();

    var start = str.indexOf(startComment);
    var end = str.lastIndexOf(endComment);

    return str.slice(start + startComment.length, -(str.length - end));
};

Example:

var tmpl = function() { /*!
 <div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
    </ul>
 </div>
*/}.extractComment();
Community
  • 1
  • 1
pocheptsov
  • 1,936
  • 20
  • 24
9

Updated for 2015: it's six years later now: most people use a module loader, and the main module systems each have ways of loading templates. It's not inline, but the most common type of multiline string are templates, and templates should generally be kept out of JS anyway.

require.js: 'require text'.

Using require.js 'text' plugin, with a multiline template in template.html

var template = require('text!template.html')

NPM/browserify: the 'brfs' module

Browserify uses a 'brfs' module to load text files. This will actually build your template into your bundled HTML.

var fs = require("fs");
var template = fs.readFileSync(template.html', 'utf8');

Easy.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
9

If you're willing to use the escaped newlines, they can be used nicely. It looks like a document with a page border.

enter image description here

seo
  • 1,959
  • 24
  • 18
8

The ES6 way of doing it would be by using template literals:

const str = `This 

is 

a

multiline text`; 

console.log(str);

More reference here

jenil christo
  • 666
  • 8
  • 16
  • This answer is not only small, incomplete and bad formatted, but also doesn't add absolutely anything to the previous answers. Flagging it and hopping to be deleted. – Victor Schröder Jan 18 '19 at 17:43
8

Easiest way to make multiline strings in Javascrips is with the use of backticks ( `` ). This allows you to create multiline strings in which you can insert variables with ${variableName}.

Example:

let name = 'Willem'; 
let age = 26;

let multilineString = `
my name is: ${name}

my age is: ${age}
`;

console.log(multilineString);

compatibility :

  • It was introduces in ES6//es2015
  • It is now natively supported by all major browser vendors (except internet explorer)

Check exact compatibility in Mozilla docs here

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
7

You can use TypeScript (JavaScript SuperSet), it supports multiline strings, and transpiles back down to pure JavaScript without overhead:

var templates = {
    myString: `this is
a multiline
string` 
}

alert(templates.myString);

If you'd want to accomplish the same with plain JavaScript:

var templates = 
{
 myString: function(){/*
    This is some
    awesome multi-lined
    string using a comment 
    inside a function 
    returned as a string.
    Enjoy the jimmy rigged code.
*/}.toString().slice(14,-3)

}
alert(templates.myString)

Note that the iPad/Safari does not support 'functionName.toString()'

If you have a lot of legacy code, you can also use the plain JavaScript variant in TypeScript (for cleanup purposes):

interface externTemplates
{
    myString:string;
}

declare var templates:externTemplates;

alert(templates.myString)

and you can use the multiline-string object from the plain JavaScript variant, where you put the templates into another file (which you can merge in the bundle).

You can try TypeScript at
http://www.typescriptlang.org/Playground

Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442
  • Any documentation on the iPad/Safari limitation? MDN seems to think it's all good - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString – Campbeln Aug 05 '17 at 18:15
  • @Campbeln: CoWorker told me this (he used the code). Haven't tested it myselfs. Might also depend on the iPad/Safari version - so probably depends. – Stefan Steiger Aug 06 '17 at 16:07
6

ES6 allows you to use a backtick to specify a string on multiple lines. It's called a Template Literal. Like this:

var multilineString = `One line of text
    second line of text
    third line of text
    fourth line of text`;

Using the backtick works in NodeJS, and it's supported by Chrome, Firefox, Edge, Safari, and Opera.

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

earl3s
  • 2,393
  • 1
  • 23
  • 24
5

You can use tagged templates to make sure you get the desired output.

For example:

// Merging multiple whitespaces and trimming the output

const t = (strings) => { return strings.map((s) => s.replace(/\s+/g, ' ')).join("").trim() }
console.log(t`
  This
  Is
  A
  Multiline
  String
`);
// Output: 'This Is A Multiline String'

// Similar but keeping whitespaces:

const tW = (strings) => { return strings.map((s) => s.replace(/\s+/g, '\n')).join("").trim() }
console.log(tW`
  This
  Is
  A
  Multiline
  String
`);
// Output: 'This\nIs\nA\nMultiline\nString'
Pedro Andrade
  • 4,556
  • 1
  • 25
  • 24
4

Also do note that, when extending string over multiple lines using forward backslash at end of each line, any extra characters (mostly spaces, tabs and comments added by mistake) after forward backslash will cause unexpected character error, which i took an hour to find out

var string = "line1\  // comment, space or tabs here raise error
line2";
Prakash GPz
  • 1,675
  • 4
  • 16
  • 27
4

Please for the love of the internet use string concatenation and opt not to use ES6 solutions for this. ES6 is NOT supported all across the board, much like CSS3 and certain browsers being slow to adapt to the CSS3 movement. Use plain ol' JavaScript, your end users will thank you.

Example:

var str = "This world is neither flat nor round. "+ "Once was lost will be found";

Pragmatiq
  • 77
  • 4
4

Multiline string with variables

var x = 1
string = string + `<label class="container">
                       <p>${x}</p>
                   </label>`;
Abhishek Goel
  • 18,785
  • 11
  • 87
  • 65
3

My version of array-based join for string concat:

var c = []; //c stands for content
c.push("<div id='thisDiv' style='left:10px'></div>");
c.push("<div onclick='showDo(\'something\');'></div>");
$(body).append(c.join('\n'));

This has worked well for me, especially as I often insert values into the html constructed this way. But it has lots of limitations. Indentation would be nice. Not having to deal with nested quotation marks would be really nice, and just the bulkyness of it bothers me.

Is the .push() to add to the array taking up a lot of time? See this related answer:

(Is there a reason JavaScript developers don't use Array.push()?)

After looking at these (opposing) test runs, it looks like .push() is fine for string arrays which will not likely grow over 100 items - I will avoid it in favor of indexed adds for larger arrays.

Community
  • 1
  • 1
KTys
  • 170
  • 1
  • 9
3

You can use += to concatenate your string, seems like no one answered that, which will be readable, and also neat... something like this

var hello = 'hello' +
            'world' +
            'blah';

can be also written as

var hello = 'hello';
    hello += ' world';
    hello += ' blah';

console.log(hello);
Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
2

You have to use the concatenation operator '+'.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <p id="demo"></p>
    <script>
        var str = "This "
                + "\n<br>is "
                + "\n<br>multiline "
                + "\n<br>string.";
        document.getElementById("demo").innerHTML = str;
     </script>
</body>
</html>

By using \n your source code will look like -

This 
 <br>is
 <br>multiline
 <br>string.

By using <br> your browser output will look like -

This
is
multiline
string.
Sonevol
  • 290
  • 3
  • 12
2

JavaScript never had a true good way to handle multiline strings, until 2015 when ES6 was introduced, along with template literals.

Template literals are strings delimited by backticks(``), instead of the normal single('')/doubl("")e quote delimiter.

NimaDoustdar
  • 318
  • 3
  • 5
1

I think this workaround should work in IE, Chrome, Firefox, Safari, Opera -

Using jQuery :

<xmp id="unique_id" style="display:none;">
  Some plain text
  Both type of quotes :  " ' " And  ' " '
  JS Code : alert("Hello World");
  HTML Code : <div class="some_class"></div>
</xmp>
<script>
   alert($('#unique_id').html());
</script>

Using Pure Javascript :

<xmp id="unique_id" style="display:none;">
  Some plain text
  Both type of quotes :  " ' " And  ' " '
  JS Code : alert("Hello World");
  HTML Code : <div class="some_class"></div>
</xmp>
<script>
   alert(document.getElementById('unique_id').innerHTML);
</script>

Cheers!!

Aditya Hajare
  • 1,372
  • 1
  • 15
  • 24
  • `` is so deprecated. It may be allowed in HTML, but should not be used by any authors. See http://stackoverflow.com/questions/8307846/why-was-the-xmp-html-tag-deprecated – Bergi Jan 28 '13 at 12:28
  • @Bergi, you are right.. and using `
    ;` with escapes wont help in my solution.. I came across similar issue today and trying to figure out a workaround.. but in my case, I found one very n00bish way to fix this issue by putting output in html comments instead of  or any other tag. lol. I know its not a standard way to do this but I will work on this issue more tomorrow mornin.. Cheers!!
    – Aditya Hajare Jan 28 '13 at 13:11
  • Unfortunately even with `style="display:none"` Chrome tries to load any `` images mentioned in the example block. – Jesse Glick Dec 09 '13 at 19:57
0

Just tried the Anonymous answer and found there's a little trick here, it doesn't work if there's a space after backslash \
So the following solution doesn't work -

var x = { test:'<?xml version="1.0"?>\ <-- One space here
            <?mso-application progid="Excel.Sheet"?>' 
};

But when space is removed it works -

var x = { test:'<?xml version="1.0"?>\<-- No space here now
          <?mso-application progid="Excel.Sheet"?>' 
};

alert(x.test);​

Hope it helps !!

Anmol Saraf
  • 15,075
  • 10
  • 50
  • 60
  • 7
    well obviously if you have a space after a backslash, backslash escapes the space. It is supposed to escape linebreak, not space. – Sejanus Dec 14 '12 at 08:47
0

This is one fairly economical approach, at least in terms of the source code:

function s() {
    var args = [],index;
    for (index = 0; index< arguments.length; index++) {
        args.push (arguments [index]);
    }
    return args.join ("\n");
}
console.log (s (
    "This is the first line",
    "and this is the second",
    "finally a third"
));

function s() {return arguments.join ("\n")} 

would be nicer of course if the "arguments" property were a proper array.

A second version might use "" to do the join for cases when you want to control the line breaks in a very long string.

Steel Brain
  • 4,321
  • 28
  • 38
  • 1
    this works: `function s() { return Array.prototype.join.call(arguments, '\n'); }` – Jan Sep 13 '15 at 05:25
0

I program this way:

sys = {
    layout: null,
    makeLayout: function (obCLS) {
        this.layout = $('<div />').addClass('editor').appendTo($(obCLS)).append(

            /* Cargador */
            /* @this.layout.find('> div:nth-of-child(1)'); */
            '<div>' +
            '   <p>Seleccione la imagen que desea procesar.</p>' +
            '   <input type="button" value="Seleccionar" class="btn btn-xlarge btn-success" />' +
            '   <span></span>' +
            '</div>' +

            /* Cargador - Progreso */
            /* @this.layout.find('> div:nth-of-child(2)'); */
            '<div>' +
            '   <div>' +
            '       <div></div>' +
            '       <div>' +
            '           <div></div>' +
            '       </div>' +
            '   </div>' +
            '</div>' +

            /* Editor */
            /* @this.layout.find('> div:nth-of-child(3)');
             * @sidebar = this.layout.find('> div:nth-of-child(3) > div > div > div:nth-of-type(1)');
             * @body    = this.layout.find('> div:nth-of-child(3) > div > div > div:nth-of-type(2) > div'); */
            '<div>' +
            '   <div>' +
            '       <div>' +
            '           <div></div>' +
            '           <div>' +
            '               <div></div>' +
            '           </div>' +
            '       </div>' +
            '   </div>' +
            '</div>'
        );
    }
}

sys.makeLayout('#div');
e-info128
  • 3,727
  • 10
  • 40
  • 57
  • 5
    that is horrendous, theres a reason people do NOT program that way – Barry Chapman Feb 18 '14 at 16:33
  • 7
    Keep HTML where it should be. In the HTML document. Hide the HTML and use jQuery to show it when it's needed. Much cleaner and much more maintainable. – Tek Mar 11 '14 at 11:22
  • Yes, I want to apologize, 7 years have passed and I no longer program that way, clearly the html code must be in html or jsx and not inside javascript code. – e-info128 Jun 15 '20 at 23:51
0

I think I discovered another way to do it inline without any invasive syntax on every line. Use Javascript's ability to convert a function to string and create a multiline comment with the /**/ syntax then remove the "function() {/*\n" and "\n*/}".

var multiline = function(string) { return string.toString().replace(/(^[^\n]*\n)|(\n\*\/\})/g, ""); };

console.log(multiline(function() {/*
Hello world!
I'm a multiline string!

Tada!
*/}));

The only pitfall I can see in this is the syntax highlighting.

EDIT: Had I scrolled down a little more, I would have seen this answer doing exactly the same thing: https://stackoverflow.com/a/5571069/916553

Community
  • 1
  • 1
AdrianCooney
  • 727
  • 5
  • 13
0

If you happen to be running in Node only, you could use the fs module to read in the multi-line string from a file:

var diagram;
var fs = require('fs');
fs.readFile( __dirname + '/diagram.txt', function (err, data) {
  if (err) {
    throw err; 
  }
  diagram = data.toString();
});
Charles Brandt
  • 981
  • 10
  • 13
0

The Rule is: when inside a string, use \n wherever you want a new line; you do not have to put a space before or after the \n, JavaScript's interpreter is smart enough to know how long the unprintable character representation is.

Sapphire_Brick
  • 1,560
  • 12
  • 26
-3

i found a more elegant solution, maybe a little non-topic related because it uses PHP, but im sure it will be useful and cuteness* for some of yours...

this javascript code should stay inside script tags

var html=<?php echo json_encode("

        <div class=container>
            <div class=area1>
                xxx
            </div>
            <div class=area2>
                ".$someVar."
            </div>
        </div>

"); ?>

in your output html you will see something like

var html="\r\n\r\n\t\t\t<div class=container>\r\n\t\t\t\t<div class=area1>\r\n\t\t\t\t\txxx\r\n\t\t\t\t<\/div>\r\n\t\t\t\t<div class=area2>\r\n\t\t\t\t\t44\r\n\t\t\t\t<\/div>\r\n\t\t\t<\/div>\r\n\r\n\t\t";  

 


and et voilà!, it gives you code readability in your file.

pD: this sample uses json_encode() PHP function, but certainly there are function equivalents for ASP, Ruby and JSP langs.

pD: however, this solution have his limitations too, one of them is you cannot use javascript variables inside the encapsulated code.

AgelessEssence
  • 6,395
  • 5
  • 33
  • 37
  • 1
    I confess I have done this a number of times to get complex quoted strings into javascript, although I pre-prepare them. But you're wrong about not being able to use javascript variables, you could implement coffee-script style *interpolations* which look like #{this.example}, and replace using a .replace regex with a closure function. – Orwellophile May 27 '15 at 10:09
-14

It's not extremely elegant but it's clean enough for me:

var myString = "First line" + "\n";
var myString = myString + "Second line" + "\n";
var myString = myString + "Third line" + "\n";
BearCode
  • 2,734
  • 6
  • 34
  • 37
  • 16
    You should use `var myString += "Second line \n";` instead. MUCH cleaner. – Colin Feb 27 '13 at 04:45
  • 13
    Actually, you should use `myString += "Second line \n";` The `var` shouldn't be repeated. – Michael Mior Jul 11 '13 at 14:04
  • 1
    use + only for concatenate strings. Not need declare all buffer for each line. Its horrorific. – e-info128 Aug 02 '13 at 15:43
  • 1
    Should I correct my answer or should I leave it there as a good example of how NOT to do things? If it's best for the people who learn JavaScript, I don't mind leaving it there as it is now. A few negative points can't hurt that much. – BearCode Nov 26 '14 at 01:04