New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On printing multiline template string in the file, fs inserts LF ( \n ) instead of CRLF ( \r\n ) #3121

Closed
vsemozhetbyt opened this Issue Sep 29, 2015 · 9 comments

Comments

Projects
None yet
3 participants
@vsemozhetbyt
Member

vsemozhetbyt commented Sep 29, 2015

Node 4.1.1 on Windows 7 x86.

1 . Here is a code:

require('fs').writeFileSync('test.txt', '\uFEFF' +
`1
2
3
`, {encoding: 'utf8'});

2 . Here is the code in hex:

in

3 . Here is the output in hex:

out

4 . What would be more predictable:

a. EOL in the output = EOL in the input.
b. EOL in the output = require('os').EOL
c. EOL in the output = an argument in the writeFileSync and other IO functions.

@cjihrig

This comment has been minimized.

Contributor

cjihrig commented Sep 29, 2015

This comes from V8, not from Node. However, I think this is expected behavior, given this text in the template literal spec:

and LineTerminatorSequences are normalized to for both TV and TRV. An explicit EscapeSequence is needed to include a or sequence.

If I'm wrong, we can reopen this.

@cjihrig cjihrig closed this Sep 29, 2015

@vsemozhetbyt

This comment has been minimized.

Member

vsemozhetbyt commented Sep 30, 2015

So if I need a file with CRLF EOL, I need to write this?

`1\r
2\r
3\r
`

Well, this is ugly and weakens all the handiness... In IO this is a doubtful decision.

@cjihrig

This comment has been minimized.

Contributor

cjihrig commented Sep 30, 2015

Looks that way. Maybe I'm wrong. Sorry.

@vsemozhetbyt

This comment has been minimized.

Member

vsemozhetbyt commented Sep 30, 2015

No, no, thank you for the explanation.

@vsemozhetbyt

This comment has been minimized.

Member

vsemozhetbyt commented Sep 30, 2015

Well, may be this is somehow better.

// node --harmony_rest_parameters test.js

require('fs').writeFileSync('test.txt', '\uFEFF' +
tagCRLF`1
2
3
`, {encoding: 'utf8'});

function tagCRLF(template, ...expressions) {
  return template.slice(1).reduce((accumulator, part, i) => {
    return accumulator + expressions[i] + part;
  }, template[0]).replace(/\n/g, '\r\n');
}

(thanks to Nicolas Bevacqua for tag function example);

Or simpler:

require('fs').writeFileSync('test.txt', '\uFEFF' +
`1
2
3
`.replace(/\n/g, '\r\n'), {encoding: 'utf8'});

@vsemozhetbyt vsemozhetbyt changed the title from On printing multiline template string in the file, fs inserts \n instead of \r\n to On printing multiline template string in the file, fs inserts LF ( \n ) instead of CRLF ( \r\n ) Sep 30, 2015

@eladkarako

This comment has been minimized.

eladkarako commented Dec 29, 2017

Note that you should probably "normalize" to Unix EOL first,
it will make sure you'll never have weird cases of \r\r\n,
also, always, always use the m RegExp-modifier when working on an ambiguous line-ending textual-content.

var fs        = require("fs")
   ,path      = require("path")
   ,file      = path.resolve("c:/path/file.txt")
   ,content   = fs.readFileSync(file,{encoding: "utf8"})
   ;
   
/*
content = ......
*/

content = content.replace(/\r\n/gm, "\n")    //normalize
                 .replace(/\n/gm,   "\r\n")  //CR+LF  -  Windows EOL
                 ;

fs.writeFileSync(file, content, {flag:"w", encoding:"utf8"}); //explicit overwrite
@vsemozhetbyt

This comment has been minimized.

Member

vsemozhetbyt commented Dec 29, 2017

Does not the m RegExp-modifier only affect the ^ and $ semantics?

@eladkarako

This comment has been minimized.

eladkarako commented Dec 30, 2017

@vsemozhetbyt "end of line" metacharacter ($) matches the end of the string, or before a terminating newline. When this modifier is set, the "start of line" and "end of line" constructs match immediately following or immediately before any newline in the subject string, respectively, as well as at the very start and end. If there are no "\n" characters in a subject string, or no occurrences of ^ or $ in a pattern, setting this modifier has no effect.

@vsemozhetbyt

This comment has been minimized.

Member

vsemozhetbyt commented Dec 30, 2017

But in your examples, there are no ^ or $. Can you provide an example how the m flag changes the behavior of a RegExp without ^ and $ symbols?

@isabellachen isabellachen referenced this issue Oct 30, 2018

Closed

Feature/hint valid doctype #1399

4 of 4 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment