js-beautify 1.5.6 → 1.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,26 @@
1
1
  # Changelog
2
+ ## v1.5.7
3
+
4
+ ### Description
5
+ * Beautifier does not break PHP and Underscore.js templates
6
+ * Fix for SCSS pseudo classes and intperpolation/mixins
7
+ * Alternative Newline Characters in CSS and HTML
8
+ * Preserve formatting or completely ignore section of javascript using comments
9
+
10
+
11
+ ### Closed Issues
12
+ * Support for legacy JavaScript versions (e.g. WSH+JScript & Co) ([#720](https://github.com/beautify-web/js-beautify/pull/720))
13
+ * Is \\n hard coded into CSS Beautifier logic? ([#715](https://github.com/beautify-web/js-beautify/issues/715))
14
+ * Spaces and linebreaks after # and around { } messing up interpolation/mixins (SASS/SCSS) ([#689](https://github.com/beautify-web/js-beautify/issues/689))
15
+ * Calls to functions get completely messed up in Sass (*.scss) ([#675](https://github.com/beautify-web/js-beautify/issues/675))
16
+ * No new line after selector in scss files ([#666](https://github.com/beautify-web/js-beautify/issues/666))
17
+ * using html-beautify on handlebars template deletes unclosed tag if on second line ([#623](https://github.com/beautify-web/js-beautify/issues/623))
18
+ * more Extra space after scss pseudo classes ([#557](https://github.com/beautify-web/js-beautify/issues/557))
19
+ * Unnecessary spaces in PHP code ([#490](https://github.com/beautify-web/js-beautify/issues/490))
20
+ * Some underscore.js template tags are broken ([#417](https://github.com/beautify-web/js-beautify/issues/417))
21
+ * Selective ignore using comments (feature request) ([#384](https://github.com/beautify-web/js-beautify/issues/384))
22
+
23
+
2
24
  ## v1.5.6
3
25
 
4
26
  ### Description
@@ -45,6 +67,7 @@
45
67
  * CSS: support add newline between rules ([#574](https://github.com/beautify-web/js-beautify/pull/574))
46
68
  * elem[array]++ changes to elem[array] ++ inserting unnecessary gap ([#570](https://github.com/beautify-web/js-beautify/issues/570))
47
69
  * add support to less functions paramters braces ([#568](https://github.com/beautify-web/js-beautify/pull/568))
70
+ * selector_separator_newline: true for Sass doesn't work ([#563](https://github.com/beautify-web/js-beautify/issues/563))
48
71
  * yield statements are being beautified to their own newlines since 1.5.2 ([#560](https://github.com/beautify-web/js-beautify/issues/560))
49
72
  * HTML beautifier inserts extra newline into `<li>`s ending with `<code>` ([#524](https://github.com/beautify-web/js-beautify/issues/524))
50
73
  * Add wrap_attributes option ([#476](https://github.com/beautify-web/js-beautify/issues/476))
@@ -117,12 +140,14 @@ https://github.com/beautify-web/js-beautify/compare/v1.5.1...v1.5.2
117
140
 
118
141
  ### Closed Issues
119
142
  * Allow custom elements to be unformatted ([#540](https://github.com/beautify-web/js-beautify/pull/540))
143
+ * Need option to ignore brace style ([#538](https://github.com/beautify-web/js-beautify/issues/538))
120
144
  * Refactor to Output and OutputLine classes ([#536](https://github.com/beautify-web/js-beautify/pull/536))
121
145
  * Recognize ObjectLiteral on open brace ([#535](https://github.com/beautify-web/js-beautify/pull/535))
122
146
  * Refactor to fully tokenize before formatting ([#530](https://github.com/beautify-web/js-beautify/pull/530))
123
147
  * Cleanup checked in six.py file ([#527](https://github.com/beautify-web/js-beautify/pull/527))
124
148
  * Changelog.md? ([#526](https://github.com/beautify-web/js-beautify/issues/526))
125
149
  * New line added between each css declaration ([#523](https://github.com/beautify-web/js-beautify/issues/523))
150
+ * Kendo Template scripts get messed up! ([#516](https://github.com/beautify-web/js-beautify/issues/516))
126
151
  * SyntaxError: Unexpected token ++ ([#514](https://github.com/beautify-web/js-beautify/issues/514))
127
152
  * space appears before open square bracket when the object name is "set" ([#508](https://github.com/beautify-web/js-beautify/issues/508))
128
153
  * Unclosed string problem ([#505](https://github.com/beautify-web/js-beautify/issues/505))
@@ -144,8 +169,17 @@ https://github.com/beautify-web/js-beautify/compare/v1.5.1...v1.5.2
144
169
  * Cannot declare object literal properties with unquoted reserved words ([#440](https://github.com/beautify-web/js-beautify/issues/440))
145
170
  * Do not put a space within `function*` generator functions. ([#428](https://github.com/beautify-web/js-beautify/issues/428))
146
171
  * beautification of "nth-child" css fails csslint ([#418](https://github.com/beautify-web/js-beautify/issues/418))
147
- * comment breaks indent ([#413](https://github.com/beautify-web/js-beautify/issues/413))
148
- * AngularJS inline templates are being corrupted! ([#385](https://github.com/beautify-web/js-beautify/issues/385))
172
+
173
+
174
+ ## v1.5.10
175
+
176
+ ### Description
177
+ Hotfix for directives
178
+ Version jump due to release script tweaks
179
+
180
+
181
+ ### Closed Issues
182
+ * Preserve directive doesn't work as intended ([#723](https://github.com/beautify-web/js-beautify/issues/723))
149
183
 
150
184
 
151
185
  ## v1.5.1
package/CONTRIBUTING.md CHANGED
@@ -58,7 +58,6 @@ NOTE: Before you do any of these make sure the latest changes have passed the tr
58
58
 
59
59
  ##Web
60
60
  Merge changes from `master` to `gh-pages` branch. This is very low cost and can be done whenever is convenient.
61
- If doing a general release, update the `bower.json` file to the new version and commit the change.
62
61
 
63
62
  ##Python
64
63
  NOTE: For now, we'd like to keep python and node version numbers synchronized,
package/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
  [![Build Status](https://img.shields.io/travis/beautify-web/js-beautify/master.svg)](http://travis-ci.org/beautify-web/js-beautify)
3
3
  [![NPM version](https://img.shields.io/npm/v/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
4
4
  [![Download stats](https://img.shields.io/npm/dm/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
5
+ [![Join the chat at https://gitter.im/beautify-web/js-beautify](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/beautify-web/js-beautify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
6
 
6
7
  [![NPM stats](https://nodei.co/npm/js-beautify.svg?downloadRank=true&downloads=true)](https://www.npmjs.org/package/js-beautify)
7
8
 
@@ -144,6 +145,30 @@ Configuration sources provided earlier in this stack will override later ones.
144
145
 
145
146
  You might notice that the CLI options and defaults hash aren't 100% correlated. Historically, the Python and JS APIs have not been 100% identical. For example, `space_before_conditional` is currently JS-only, and not addressable from the CLI script. There are a few other additional cases keeping us from 100% API-compatibility. Patches welcome!
146
147
 
148
+ ## Directives to Ignore or Preserve sections (Javascript only)
149
+
150
+ Beautifier for supports directives in comments inside the file.
151
+ This allows you to tell the beautifier to preserve the formtatting of or completely ignore part of a file.
152
+ The example input below will remain changed after beautification
153
+
154
+ ```js
155
+ // Use preserve when the content is not javascript, but you don't want it reformatted.
156
+ /* beautify preserve:start */
157
+ {
158
+ browserName: 'internet explorer',
159
+ platform: 'Windows 7',
160
+ version: '8'
161
+ }
162
+ /* beautify preserve:end */
163
+
164
+ // Use ignore when the content is not parsable as javascript.
165
+ var a = 1;
166
+ /* beautify ignore:start */
167
+ {This is some strange{template language{using open-braces?
168
+ /* beautify ignore:end */
169
+ ```
170
+
171
+
147
172
  ### CSS & HTML
148
173
 
149
174
  In addition to the `js-beautify` executable, `css-beautify` and `html-beautify` are also provided as an easy interface into those scripts. Alternatively, `js-beautify --css` or `js-beautify --html` will accomplish the same thing, respectively.
@@ -163,22 +188,27 @@ The CSS & HTML beautifiers are much simpler in scope, and possess far fewer opti
163
188
  CSS Beautifier Options:
164
189
  -s, --indent-size Indentation size [4]
165
190
  -c, --indent-char Indentation character [" "]
191
+ -t, --indent-with-tabs Indent with tabs, overrides -s and -c
192
+ -e, --eol Character(s) to use as line terminators. (default newline - "\\n")
193
+ -n, --end-with-newline End output with newline
166
194
  -L, --selector-separator-newline Add a newline between multiple selectors
167
195
  -N, --newline-between-rules Add a newline between CSS rules
168
196
 
169
197
  HTML Beautifier Options:
170
- -I, --indent-inner-html Indent <head> and <body> sections. Default is false.
171
198
  -s, --indent-size Indentation size [4]
172
199
  -c, --indent-char Indentation character [" "]
200
+ -t, --indent-with-tabs Indent with tabs, overrides -s and -c
201
+ -e, --eol Character(s) to use as line terminators. (default newline - "\\n")
202
+ -n, --end-with-newline End output with newline
203
+ -p, --preserve-newlines Preserve existing line-breaks (--no-preserve-newlines disables)
204
+ -m, --max-preserve-newlines Maximum number of line-breaks to be preserved in one chunk [10]
205
+ -I, --indent-inner-html Indent <head> and <body> sections. Default is false.
173
206
  -b, --brace-style [collapse|expand|end-expand|none] ["collapse"]
174
207
  -S, --indent-scripts [keep|separate|normal] ["normal"]
175
208
  -w, --wrap-line-length Maximum characters per line (0 disables) [250]
176
209
  -A, --wrap-attributes Wrap attributes to new lines [auto|force] ["auto"]
177
210
  -i, --wrap-attributes-indent-size Indent wrapped attributes to after N characters [indent-size]
178
- -p, --preserve-newlines Preserve existing line-breaks (--no-preserve-newlines disables)
179
- -m, --max-preserve-newlines Maximum number of line-breaks to be preserved in one chunk [10]
180
211
  -U, --unformatted List of tags (defaults to inline) that should not be reformatted
181
- -n, --end-with-newline End output with newline
182
212
  -E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline before them.
183
213
  ```
184
214
 
@@ -198,4 +228,4 @@ Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, D
198
228
  Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
199
229
  Mathias Bynens, Vittorio Gambaletta and others.
200
230
 
201
- js-beautify@1.5.5
231
+ js-beautify@1.5.7
package/bower.json CHANGED
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "name": "js-beautify",
3
- "version": "1.5.6",
4
3
  "main": [
5
4
  "./js/lib/beautify.js",
6
5
  "./js/lib/beautify-css.js",
@@ -63,11 +63,16 @@
63
63
  (function() {
64
64
  function css_beautify(source_text, options) {
65
65
  options = options || {};
66
+ source_text = source_text || '';
67
+ // HACK: newline parsing inconsistent. This brute force normalizes the input.
68
+ source_text = source_text.replace(/\r\n|[\r\u2028\u2029]/g, '\n')
69
+
66
70
  var indentSize = options.indent_size || 4;
67
71
  var indentCharacter = options.indent_char || ' ';
68
72
  var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
69
73
  var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
70
74
  var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
75
+ var eol = options.eol ? options.eol : '\n';
71
76
 
72
77
  // compatibility
73
78
  if (typeof indentSize === "string") {
@@ -79,6 +84,9 @@
79
84
  indentSize = 1;
80
85
  }
81
86
 
87
+ eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n')
88
+
89
+
82
90
  // tokenizer
83
91
  var whiteRe = /^\s+$/;
84
92
  var wordRe = /[\w$\-_]/;
@@ -172,11 +180,20 @@
172
180
  // and the next special character found opens
173
181
  // a new block
174
182
  function foundNestedPseudoClass() {
183
+ var openParen = 0;
175
184
  for (var i = pos + 1; i < source_text.length; i++) {
176
185
  var ch = source_text.charAt(i);
177
186
  if (ch === "{") {
178
187
  return true;
179
- } else if (ch === ";" || ch === "}" || ch === ")") {
188
+ } else if (ch === '(') {
189
+ // pseudoclasses can contain ()
190
+ openParen += 1;
191
+ } else if (ch === ')') {
192
+ if (openParen == 0) {
193
+ return false;
194
+ }
195
+ openParen -= 1;
196
+ } else if (ch === ";" || ch === "}") {
180
197
  return false;
181
198
  }
182
199
  }
@@ -234,6 +251,12 @@
234
251
  }
235
252
  };
236
253
 
254
+ print.preserveSingleSpace = function() {
255
+ if (isAfterSpace) {
256
+ print.singleSpace();
257
+ }
258
+ };
259
+
237
260
  print.trim = function() {
238
261
  while (print._lastCharWhitespace()) {
239
262
  output.pop();
@@ -245,6 +268,7 @@
245
268
  /*_____________________--------------------_____________________*/
246
269
 
247
270
  var insideRule = false;
271
+ var insidePropertyValue = false;
248
272
  var enteringConditionalGroup = false;
249
273
  var top_ch = '';
250
274
  var last_top_ch = '';
@@ -278,10 +302,7 @@
278
302
  output.push(eatComment());
279
303
  print.newLine();
280
304
  } else if (ch === '@') {
281
- // pass along the space we found as a separate item
282
- if (isAfterSpace) {
283
- print.singleSpace();
284
- }
305
+ print.preserveSingleSpace();
285
306
  output.push(ch);
286
307
 
287
308
  // strip trailing space, if present, for hash property checks
@@ -304,6 +325,9 @@
304
325
  enteringConditionalGroup = true;
305
326
  }
306
327
  }
328
+ } else if (ch === '#' && peek() === '{') {
329
+ print.preserveSingleSpace();
330
+ output.push(eatString('}'));
307
331
  } else if (ch === '{') {
308
332
  if (peek(true) === '}') {
309
333
  eatWhitespace();
@@ -330,6 +354,7 @@
330
354
  outdent();
331
355
  print["}"](ch);
332
356
  insideRule = false;
357
+ insidePropertyValue = false;
333
358
  if (nestedLevel) {
334
359
  nestedLevel--;
335
360
  }
@@ -342,6 +367,7 @@
342
367
  !(lookBack("&") || foundNestedPseudoClass())) {
343
368
  // 'property: value' delimiter
344
369
  // which could be in a conditional group query
370
+ insidePropertyValue = true;
345
371
  output.push(':');
346
372
  print.singleSpace();
347
373
  } else {
@@ -357,11 +383,10 @@
357
383
  }
358
384
  }
359
385
  } else if (ch === '"' || ch === '\'') {
360
- if (isAfterSpace) {
361
- print.singleSpace();
362
- }
386
+ print.preserveSingleSpace();
363
387
  output.push(eatString(ch));
364
388
  } else if (ch === ';') {
389
+ insidePropertyValue = false;
365
390
  output.push(ch);
366
391
  print.newLine();
367
392
  } else if (ch === '(') { // may be a url
@@ -377,9 +402,7 @@
377
402
  }
378
403
  } else {
379
404
  parenLevel++;
380
- if (isAfterSpace) {
381
- print.singleSpace();
382
- }
405
+ print.preserveSingleSpace();
383
406
  output.push(ch);
384
407
  eatWhitespace();
385
408
  }
@@ -389,7 +412,7 @@
389
412
  } else if (ch === ',') {
390
413
  output.push(ch);
391
414
  eatWhitespace();
392
- if (!insideRule && selectorSeparatorNewline && parenLevel < 1) {
415
+ if (selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
393
416
  print.newLine();
394
417
  } else {
395
418
  print.singleSpace();
@@ -397,19 +420,14 @@
397
420
  } else if (ch === ']') {
398
421
  output.push(ch);
399
422
  } else if (ch === '[') {
400
- if (isAfterSpace) {
401
- print.singleSpace();
402
- }
423
+ print.preserveSingleSpace();
403
424
  output.push(ch);
404
425
  } else if (ch === '=') { // no whitespace before or after
405
426
  eatWhitespace()
406
427
  ch = '=';
407
428
  output.push(ch);
408
429
  } else {
409
- if (isAfterSpace) {
410
- print.singleSpace();
411
- }
412
-
430
+ print.preserveSingleSpace();
413
431
  output.push(ch);
414
432
  }
415
433
  }
@@ -424,7 +442,11 @@
424
442
 
425
443
  // establish end_with_newline
426
444
  if (end_with_newline) {
427
- sweetCode += "\n";
445
+ sweetCode += '\n';
446
+ }
447
+
448
+ if (eol != '\n') {
449
+ sweetCode = sweetCode.replace(/[\n]/g, eol);
428
450
  }
429
451
 
430
452
  return sweetCode;
@@ -101,7 +101,8 @@
101
101
  wrap_attributes,
102
102
  wrap_attributes_indent_size,
103
103
  end_with_newline,
104
- extra_liners;
104
+ extra_liners,
105
+ eol;
105
106
 
106
107
  options = options || {};
107
108
 
@@ -116,7 +117,9 @@
116
117
  indent_character = (options.indent_char === undefined) ? ' ' : options.indent_char;
117
118
  brace_style = (options.brace_style === undefined) ? 'collapse' : options.brace_style;
118
119
  wrap_line_length = parseInt(options.wrap_line_length, 10) === 0 ? 32786 : parseInt(options.wrap_line_length || 250, 10);
119
- unformatted = options.unformatted || ['a', 'span', 'img', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
120
+ unformatted = options.unformatted || ['a', 'span', 'img', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd',
121
+ 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike',
122
+ 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
120
123
  preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;
121
124
  max_preserve_newlines = preserve_newlines ?
122
125
  (isNaN(parseInt(options.max_preserve_newlines, 10)) ? 32786 : parseInt(options.max_preserve_newlines, 10))
@@ -125,15 +128,18 @@
125
128
  wrap_attributes = (options.wrap_attributes === undefined) ? 'auto' : options.wrap_attributes;
126
129
  wrap_attributes_indent_size = (options.wrap_attributes_indent_size === undefined) ? indent_size : parseInt(options.wrap_attributes_indent_size, 10) || indent_size;
127
130
  end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
128
- extra_liners = Array.isArray(options.extra_liners) ?
131
+ extra_liners = (typeof options.extra_liners == 'object') && options.extra_liners ?
129
132
  options.extra_liners.concat() : (typeof options.extra_liners === 'string') ?
130
133
  options.extra_liners.split(',') : 'head,body,/html'.split(',');
134
+ eol = options.eol ? options.eol : '\n';
131
135
 
132
136
  if(options.indent_with_tabs){
133
137
  indent_character = '\t';
134
138
  indent_size = 1;
135
139
  }
136
140
 
141
+ eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n')
142
+
137
143
  function Parser() {
138
144
 
139
145
  this.pos = 0; //Parser position
@@ -151,7 +157,7 @@
151
157
 
152
158
  this.Utils = { //Uilities made available to the various functions
153
159
  whitespace: "\n\r\t ".split(''),
154
- single_token: 'br,input,link,meta,source,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
160
+ single_token: 'br,input,link,meta,source,!doctype,basefont,base,area,hr,wbr,param,img,isindex,embed'.split(','), //all the single tags for HTML
155
161
  extra_liners: extra_liners, //for tags that need a line of whitespace before them
156
162
  in_array: function(what, arr) {
157
163
  for (var i = 0; i < arr.length; i++) {
@@ -404,7 +410,7 @@
404
410
  this.line_char_count++;
405
411
  content.push(input_char); //inserts character at-a-time (or string)
406
412
 
407
- if (content[1] && content[1] === '!') { //if we're in a comment, do something special
413
+ if (content[1] && (content[1] === '!' || content[1] === '?' || content[1] === '%')) { //if we're in a comment, do something special
408
414
  // We treat all comments as literals, even more than preformatted tags
409
415
  // we just look for the appropriate close tag
410
416
  content = [this.get_comment(tag_start)];
@@ -429,15 +435,15 @@
429
435
 
430
436
  if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
431
437
  tag_index = tag_complete.indexOf(' ');
432
- } else if (tag_complete[0] === '{') {
438
+ } else if (tag_complete.charAt(0) === '{') {
433
439
  tag_index = tag_complete.indexOf('}');
434
440
  } else { //otherwise go with the tag ending
435
441
  tag_index = tag_complete.indexOf('>');
436
442
  }
437
- if (tag_complete[0] === '<' || !indent_handlebars) {
443
+ if (tag_complete.charAt(0) === '<' || !indent_handlebars) {
438
444
  tag_offset = 1;
439
445
  } else {
440
- tag_offset = tag_complete[2] === '#' ? 3 : 2;
446
+ tag_offset = tag_complete.charAt(2) === '#' ? 3 : 2;
441
447
  }
442
448
  var tag_check = tag_complete.substring(tag_offset, tag_index).toLowerCase();
443
449
  if (tag_complete.charAt(tag_complete.length - 2) === '/' ||
@@ -445,7 +451,7 @@
445
451
  if (!peek) {
446
452
  this.tag_type = 'SINGLE';
447
453
  }
448
- } else if (indent_handlebars && tag_complete[0] === '{' && tag_check === 'else') {
454
+ } else if (indent_handlebars && tag_complete.charAt(0) === '{' && tag_check === 'else') {
449
455
  if (!peek) {
450
456
  this.indent_to_tag('if');
451
457
  this.tag_type = 'HANDLEBARS_ELSE';
@@ -525,7 +531,7 @@
525
531
  comment += input_char;
526
532
 
527
533
  // only need to check for the delimiter if the last chars match
528
- if (comment[comment.length - 1] === delimiter[delimiter.length - 1] &&
534
+ if (comment.charAt(comment.length - 1) === delimiter.charAt(delimiter.length - 1) &&
529
535
  comment.indexOf(delimiter) !== -1) {
530
536
  break;
531
537
  }
@@ -547,6 +553,12 @@
547
553
  } else if (comment.indexOf('{{!') === 0) { // {{! handlebars comment
548
554
  delimiter = '}}';
549
555
  matched = true;
556
+ } else if (comment.indexOf('<?') === 0) { // {{! handlebars comment
557
+ delimiter = '?>';
558
+ matched = true;
559
+ } else if (comment.indexOf('<%') === 0) { // {{! handlebars comment
560
+ delimiter = '%>';
561
+ matched = true;
550
562
  }
551
563
  }
552
564
 
@@ -596,7 +608,7 @@
596
608
  this.line_char_count++;
597
609
  space = true;
598
610
 
599
- if (indent_handlebars && input_char === '{' && content.length && content[content.length - 2] === '{') {
611
+ if (indent_handlebars && input_char === '{' && content.length && content.charAt(content.length - 2) === '{') {
600
612
  // Handlebars expressions in strings should also be unformatted.
601
613
  content += this.get_unformatted('}}');
602
614
  // These expressions are opaque. Ignore delimiters found in them.
@@ -676,6 +688,10 @@
676
688
  this.printer = function(js_source, indent_character, indent_size, wrap_line_length, brace_style) { //handles input/output and some other printing functions
677
689
 
678
690
  this.input = js_source || ''; //gets the input for the Parser
691
+
692
+ // HACK: newline parsing inconsistent. This brute force normalizes the input.
693
+ this.input = this.input.replace(/\r\n|[\r\u2028\u2029]/g, '\n')
694
+
679
695
  this.output = [];
680
696
  this.indent_character = indent_character;
681
697
  this.indent_string = '';
@@ -731,7 +747,7 @@
731
747
  }
732
748
 
733
749
  if (text && text !== '') {
734
- if (text.length > 1 && text[text.length - 1] === '\n') {
750
+ if (text.length > 1 && text.charAt(text.length - 1) === '\n') {
735
751
  // unformatted tags can grab newlines as their last character
736
752
  this.output.push(text.slice(0, -1));
737
753
  this.print_newline(false, this.output);
@@ -851,8 +867,14 @@
851
867
 
852
868
  var indentation = multi_parser.get_full_indent(script_indent_level);
853
869
  if (_beautifier) {
870
+
854
871
  // call the Beautifier if avaliable
855
- text = _beautifier(text.replace(/^\s*/, indentation), options);
872
+ var Child_options = function() {
873
+ this.eol = '\n';
874
+ };
875
+ Child_options.prototype = options;
876
+ var child_options = new Child_options();
877
+ text = _beautifier(text.replace(/^\s*/, indentation), child_options);
856
878
  } else {
857
879
  // simply indent the string otherwise
858
880
  var white = text.match(/^\s*/)[0];
@@ -881,9 +903,16 @@
881
903
  multi_parser.last_text = multi_parser.token_text;
882
904
  }
883
905
  var sweet_code = multi_parser.output.join('').replace(/[\r\n\t ]+$/, '');
906
+
907
+ // establish end_with_newline
884
908
  if (end_with_newline) {
885
909
  sweet_code += '\n';
886
910
  }
911
+
912
+ if (eol != '\n') {
913
+ sweet_code = sweet_code.replace(/[\n]/g, eol);
914
+ }
915
+
887
916
  return sweet_code;
888
917
  }
889
918