Giter Club home page Giter Club logo

multiline's Introduction

multiline Build Status

Multiline strings in JavaScript

No more string concatenation or array join!

Use ES2015 template literals instead whenever possible.

Before

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

After

const str = multiline(()=>{/*
<!doctype html>
<html>
	<body>
		<h1>❤ unicorns</h1>
	</body>
</html>
*/});

How

It works by wrapping the text in a block comment, anonymous function, and a function call. The anonymous function is passed into the function call and the contents of the comment extracted.

Even though it's slower than string concat, that shouldn't realistically matter as you can still do 2 million of those a second. Convenience over micro performance always.

Install

$ npm install multiline

Usage

Everything after the first newline and before the last will be returned as seen below:

const str = multiline(()=>{/*
<!doctype html>
<html>
	<body>
		<h1>❤ unicorns</h1>
	</body>
</html>
*/});

Which outputs:

<!doctype html>
<html>
	<body>
		<h1>❤ unicorns</h1>
	</body>
</html>

Strip indent

You can use multiline.stripIndent() to be able to indent your multiline string without preserving the redundant leading whitespace.

	const str = multiline.stripIndent(()=>{/*
			<!doctype html>
			<html>
				<body>
					<h1>❤ unicorns</h1>
				</body>
			</html>
	*/});

Which outputs:

<!doctype html>
<html>
	<body>
		<h1>❤ unicorns</h1>
	</body>
</html>

String substitution

console.log() supports string substitution:

const str = 'unicorns';

console.log(multiline(()=>{/*
  I love %s
*/}), str);

//=> 'I love unicorns'

Use cases

Have one? Let me know.

Experiment

I've also done an experiment where you don't need the anonymous function. It's too fragile and slow to be practical though.

It generates a callstack and extracts the contents of the comment in the function call.

const str = multiline(/*
<!doctype html>
<html>
	<body>
		<h1>❤ unicorns</h1>
	</body>
</html>
*/);

FAQ

But JS already has multiline strings with \?

const str = 'foo\
bar';

This is not a multiline string. It's line-continuation. It doesn't preserve newlines, which is the main reason for wanting multiline strings.

You would need to do the following:

const str = 'foo\n\
bar';

But then you could just as well concatenate:

const str = 'foo\n' +
'bar';

Browser

While it does work fine in the browser, it's mainly intended for use in Node.js. Use at your own risk.

$ npm install multiline

With Webpack, Browserify, or something similar.

Compatibility

  • Latest Chrome
  • Firefox >=17
  • Safari >=4
  • Opera >=9
  • Internet Explorer >=6

Minification

Even though minifiers strip comments by default there are ways to preserve them:

  • Uglify: Use /*@preserve instead of /* and enable the comments option
  • Closure Compiler: Use /*@preserve instead of /*
  • YUI Compressor: Use /*! instead of /*

You also need to add console.log after the comment so it's not removed as dead-code.

The final result would be:

const str = multiline(function(){/*!@preserve
<!doctype html>
<html>
	<body>
		<h1>❤ unicorns</h1>
	</body>
</html>
*/console.log});

License

MIT © Sindre Sorhus

multiline's People

Contributors

freethejazz avatar sheerun avatar sindresorhus avatar stevemao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

multiline's Issues

Optimization (~2x) on Firefox

I have replaced the regular expression to use just indexOf and substr. it turns to be twice as fast in Firefox Nightly, but doesnt seems to affect on Chrome. I guess regular expression engine in V8 is better than the Mozilla one.

Here's the test: http://jsfiddle.net/8Nn4T/

How to go without `requirejs`

Hi! Thank you for useful software.

I'm using it like this, in an essentially adapted way, because I didn't want to add requirejs as a dependency.

I'd love to know how a more experienced JavaScript developer would have done it.

Multiline strings are gone when using uglifyify

Comments are being stripped out in the final bundle when using uglifyify module.

To reproduce the issue, first install these modules:

# npm install -g watchify
# npm install uglifyify

Then just create a simple file test.js:

var multiline = require("multiline");

var str = multiline(function(){/*@preserve
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/console.log});

console.log("Starting multiline test:");
console.log(str);
console.log("Finished multiline test:");

First check the bundle.js is alright without uglifying the code:

> watchify test.js -o bundle.js -v
1911 bytes written to bundle.js (0.06 seconds)
> grep unicorns bundle.js
        <h1>❤ unicorns</h1>

BUT when you use -t uglifyify transformation as explained in the documentation:

> watchify test.js -o bundle.js -v -t [uglifyify --comments]
1799 bytes written to bundle.js (0.13 seconds)

You'll see the multiline string isn't in the bundle anymore:
> grep unicorns bundle.js

Am I missing something here or is it a bug?

Error in chinese string

When I console this

var welcome = this.yeoman + multiline.stripIndent(function () {/*
  _Project Name_ should not contain "jquery" or "js" and should be a unique ID not already in use at plugins.jquery.com.

  _Project title_ should be a human-readable title, and doesn't need to contain the word "jQuery", although it may.

  For example, a plugin titled "Awesome Plugin" might have the name "awesome-plugin".

  For more information, please see the following documentation: 你們好好好好厲害

  Naming Your Plugin      http://plugins.jquery.com/docs/names/
  Publishing Your Plugin  http://plugins.jquery.com/docs/publish/
  Package Manifest        http://plugins.jquery.com/docs/package-manifest/
*/});

the phrase

For more information, please see the following documentation: 你們好好好好厲害

is broken

screen shot 2014-05-02 at 9 51 01 am

Can not use js compress tool for multiline function

Can not use js compress tool for multiline function, for example

var str = multiline(function(){/*
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/});

after compress (use YUI Compressor)

var str=multiline(function(){});

So do you have some method to handle this case.

hello uglify keep multiline seems not work

Uglify: Use /@preserve instead of / and enable the comments option
i have try

var str = multiline(function(){/*!@preserve
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/0});
var str = multiline(function(){/*@preserve
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/0});
uglify.minify(str, {
  fromString: true
  ,output: {
    comments: true
  }
})

all the str yields

var str=multiline(function(){})

these cases should throw exception

this case should throw exception:

multiline(function () {
// test invalid content
/*
valid content
*/
});

this case should throw too:

multiline(function () {
/*
valid content
*/
/*
valid content 2
*/
});

Having javascript multiline comments (/* ... */) inside the multiline string

Is it possible to have multiline js style comments (/*... */) in the string? One convoluted use case is having commented CDATA blocks in one's svg markup for css styles.

multiline(function(){
/*
<svg>
<style>
  /* <![CDATA[ */
    rect {
      fill: salmon;
    }
  /* ]]> */
</style>
</svg>


*/        })

That just generates an expected SyntaxError: Unexpected token < error and non of the escaping i've tried seems to generate the desired comments.

I can skip the CDATA blocks or put the styles in my separate stylesheets rather than the tag, so this is not blocking, but I was curious about it.

Preprocessor task

Have you thought about having a pre processor task that would go through looking for use of this method and converting it into "valid" JS? That way it could be used in build processes that strip comments.

Example of non-matching multiline (when it should)

Simply forgetting to give a LF at the end is enough for it not to 'parse' the comment:

multiline(function (){/*
<pre>
    should retain whitespace
</pre>*/
});

nor

multiline(function (){/*
<pre>
    should retain whitespace
</pre> */});

if this is by design, should go in the README, that it always expect an empty LF at the end of the comment.

browser compatible version

do you maintain a version compatible within a browser? the module.exports does not play nice within a browser :(

Code based unicode symbols

Do you think it's possible to extend multiline to support unicode characters?

In my tests I need to prepare multi line text including control characters, like this

console.log(multiline(function(){/*
\0
\u0000
*/}));

But the \ is escaped and displayed as a \, I'd like to insert the \0 control character in the string.

Why

Why would you use the comment approach instead of just:

var str = '<!doctype html>\
<html>\
    <body>\
        <h1>Hello world!</h1>\
    </body>\
</html>';

Using comments also means you leave out the option of running the through a minifier for production.

not an issue

I was just impressed
by this awesome idea!
very cunning!

Support for `util.format`?

It'd be great to be able to do something like...

var str = multiline(function(){/*
<!doctype html>
<html>
    <body>
        <h1>%s has %d %s</h1>
    </body>
</html>
*/}, 'Sindre', 4, 'unicorns')

String interpolation

Check out my fork of this project, I implemented string interpolation. It would be awesome to have that feature.

Closure Compiler, Minification strips comments, @preserve / @license not working

Hello I'm trying to minify js file that uses multiline.
I do exacly what you told me in readme, that is starting comment block with @preserve and adding console.log at the end.
Unfortunately this is not working :(
Please help!
Thank You!
Safety third!
Smoke cigarettes!

Online Closure Compiler Service:
https://closure-compiler.appspot.com/home

Input:

var tpl = $(multiline
  .stripIndent(function(){/*@preserve
    Lorem
  */console.log}))

Output:

$(multiline.a(function(){console.log}));

Expected output:

$(multiline.a(function(){/*Lorem*/console.log}));

Add another use case

I've been using this for query strings, like so(parameterized, in this case):

exports.upsertOne = multiline(function(){/*
  MERGE (n:Person {screen_name: {screenName}})
  ON CREATE SET n={userMap}
  RETURN n
*/});

This is for an app I'm working on with Neo4j, so the query language is Cypher, but I imagine it'll have just as much value for other query languages, too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.