@herb-tools/formatter 0.8.6 → 0.8.8
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/dist/herb-format.js +16962 -31496
- package/dist/herb-format.js.map +1 -1
- package/dist/index.cjs +60 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +60 -23
- package/dist/index.esm.js.map +1 -1
- package/package.json +6 -5
- package/src/cli.ts +1 -1
- package/src/format-printer.ts +25 -19
package/dist/index.cjs
CHANGED
|
@@ -66,6 +66,18 @@ function createDedent(options) {
|
|
|
66
66
|
if (escapeSpecialCharacters) {
|
|
67
67
|
result = result.replace(/\\n/g, "\n");
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
// Workaround for Bun issue with Unicode characters
|
|
71
|
+
// https://github.com/oven-sh/bun/issues/8745
|
|
72
|
+
if (typeof Bun !== "undefined") {
|
|
73
|
+
result = result.replace(
|
|
74
|
+
// Matches e.g. \\u{1f60a} or \\u5F1F
|
|
75
|
+
/\\u(?:\{([\da-fA-F]{1,6})\}|([\da-fA-F]{4}))/g, (_, braced, unbraced) => {
|
|
76
|
+
var _ref;
|
|
77
|
+
const hex = (_ref = braced !== null && braced !== void 0 ? braced : unbraced) !== null && _ref !== void 0 ? _ref : "";
|
|
78
|
+
return String.fromCodePoint(parseInt(hex, 16));
|
|
79
|
+
});
|
|
80
|
+
}
|
|
69
81
|
return result;
|
|
70
82
|
}
|
|
71
83
|
}
|
|
@@ -243,7 +255,7 @@ class Token {
|
|
|
243
255
|
}
|
|
244
256
|
|
|
245
257
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
246
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
258
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/errors.ts.erb
|
|
247
259
|
class HerbError {
|
|
248
260
|
type;
|
|
249
261
|
message;
|
|
@@ -808,7 +820,7 @@ function convertToUTF8(string) {
|
|
|
808
820
|
}
|
|
809
821
|
|
|
810
822
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
811
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
823
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/nodes.ts.erb
|
|
812
824
|
class Node {
|
|
813
825
|
type;
|
|
814
826
|
location;
|
|
@@ -1882,6 +1894,7 @@ class ERBIfNode extends Node {
|
|
|
1882
1894
|
tag_opening;
|
|
1883
1895
|
content;
|
|
1884
1896
|
tag_closing;
|
|
1897
|
+
then_keyword;
|
|
1885
1898
|
statements;
|
|
1886
1899
|
subsequent;
|
|
1887
1900
|
end_node;
|
|
@@ -1896,6 +1909,7 @@ class ERBIfNode extends Node {
|
|
|
1896
1909
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
1897
1910
|
content: data.content ? Token.from(data.content) : null,
|
|
1898
1911
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
1912
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
1899
1913
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
1900
1914
|
subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
|
|
1901
1915
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -1906,6 +1920,7 @@ class ERBIfNode extends Node {
|
|
|
1906
1920
|
this.tag_opening = props.tag_opening;
|
|
1907
1921
|
this.content = props.content;
|
|
1908
1922
|
this.tag_closing = props.tag_closing;
|
|
1923
|
+
this.then_keyword = props.then_keyword;
|
|
1909
1924
|
this.statements = props.statements;
|
|
1910
1925
|
this.subsequent = props.subsequent;
|
|
1911
1926
|
this.end_node = props.end_node;
|
|
@@ -1938,6 +1953,7 @@ class ERBIfNode extends Node {
|
|
|
1938
1953
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
1939
1954
|
content: this.content ? this.content.toJSON() : null,
|
|
1940
1955
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
1956
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
1941
1957
|
statements: this.statements.map(node => node.toJSON()),
|
|
1942
1958
|
subsequent: this.subsequent ? this.subsequent.toJSON() : null,
|
|
1943
1959
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -1950,6 +1966,7 @@ class ERBIfNode extends Node {
|
|
|
1950
1966
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
1951
1967
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
1952
1968
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
1969
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
1953
1970
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
1954
1971
|
output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
|
|
1955
1972
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2031,6 +2048,7 @@ class ERBWhenNode extends Node {
|
|
|
2031
2048
|
tag_opening;
|
|
2032
2049
|
content;
|
|
2033
2050
|
tag_closing;
|
|
2051
|
+
then_keyword;
|
|
2034
2052
|
statements;
|
|
2035
2053
|
static get type() {
|
|
2036
2054
|
return "AST_ERB_WHEN_NODE";
|
|
@@ -2043,6 +2061,7 @@ class ERBWhenNode extends Node {
|
|
|
2043
2061
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2044
2062
|
content: data.content ? Token.from(data.content) : null,
|
|
2045
2063
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2064
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2046
2065
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2047
2066
|
});
|
|
2048
2067
|
}
|
|
@@ -2051,6 +2070,7 @@ class ERBWhenNode extends Node {
|
|
|
2051
2070
|
this.tag_opening = props.tag_opening;
|
|
2052
2071
|
this.content = props.content;
|
|
2053
2072
|
this.tag_closing = props.tag_closing;
|
|
2073
|
+
this.then_keyword = props.then_keyword;
|
|
2054
2074
|
this.statements = props.statements;
|
|
2055
2075
|
}
|
|
2056
2076
|
accept(visitor) {
|
|
@@ -2077,6 +2097,7 @@ class ERBWhenNode extends Node {
|
|
|
2077
2097
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2078
2098
|
content: this.content ? this.content.toJSON() : null,
|
|
2079
2099
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2100
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2080
2101
|
statements: this.statements.map(node => node.toJSON()),
|
|
2081
2102
|
};
|
|
2082
2103
|
}
|
|
@@ -2087,6 +2108,7 @@ class ERBWhenNode extends Node {
|
|
|
2087
2108
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2088
2109
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2089
2110
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2111
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2090
2112
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2091
2113
|
return output;
|
|
2092
2114
|
}
|
|
@@ -2705,6 +2727,7 @@ class ERBUnlessNode extends Node {
|
|
|
2705
2727
|
tag_opening;
|
|
2706
2728
|
content;
|
|
2707
2729
|
tag_closing;
|
|
2730
|
+
then_keyword;
|
|
2708
2731
|
statements;
|
|
2709
2732
|
else_clause;
|
|
2710
2733
|
end_node;
|
|
@@ -2719,6 +2742,7 @@ class ERBUnlessNode extends Node {
|
|
|
2719
2742
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2720
2743
|
content: data.content ? Token.from(data.content) : null,
|
|
2721
2744
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2745
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2722
2746
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2723
2747
|
else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
|
|
2724
2748
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -2729,6 +2753,7 @@ class ERBUnlessNode extends Node {
|
|
|
2729
2753
|
this.tag_opening = props.tag_opening;
|
|
2730
2754
|
this.content = props.content;
|
|
2731
2755
|
this.tag_closing = props.tag_closing;
|
|
2756
|
+
this.then_keyword = props.then_keyword;
|
|
2732
2757
|
this.statements = props.statements;
|
|
2733
2758
|
this.else_clause = props.else_clause;
|
|
2734
2759
|
this.end_node = props.end_node;
|
|
@@ -2761,6 +2786,7 @@ class ERBUnlessNode extends Node {
|
|
|
2761
2786
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2762
2787
|
content: this.content ? this.content.toJSON() : null,
|
|
2763
2788
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2789
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2764
2790
|
statements: this.statements.map(node => node.toJSON()),
|
|
2765
2791
|
else_clause: this.else_clause ? this.else_clause.toJSON() : null,
|
|
2766
2792
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -2773,6 +2799,7 @@ class ERBUnlessNode extends Node {
|
|
|
2773
2799
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2774
2800
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2775
2801
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2802
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2776
2803
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
2777
2804
|
output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
|
|
2778
2805
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2839,6 +2866,7 @@ class ERBInNode extends Node {
|
|
|
2839
2866
|
tag_opening;
|
|
2840
2867
|
content;
|
|
2841
2868
|
tag_closing;
|
|
2869
|
+
then_keyword;
|
|
2842
2870
|
statements;
|
|
2843
2871
|
static get type() {
|
|
2844
2872
|
return "AST_ERB_IN_NODE";
|
|
@@ -2851,6 +2879,7 @@ class ERBInNode extends Node {
|
|
|
2851
2879
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2852
2880
|
content: data.content ? Token.from(data.content) : null,
|
|
2853
2881
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2882
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2854
2883
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2855
2884
|
});
|
|
2856
2885
|
}
|
|
@@ -2859,6 +2888,7 @@ class ERBInNode extends Node {
|
|
|
2859
2888
|
this.tag_opening = props.tag_opening;
|
|
2860
2889
|
this.content = props.content;
|
|
2861
2890
|
this.tag_closing = props.tag_closing;
|
|
2891
|
+
this.then_keyword = props.then_keyword;
|
|
2862
2892
|
this.statements = props.statements;
|
|
2863
2893
|
}
|
|
2864
2894
|
accept(visitor) {
|
|
@@ -2885,6 +2915,7 @@ class ERBInNode extends Node {
|
|
|
2885
2915
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2886
2916
|
content: this.content ? this.content.toJSON() : null,
|
|
2887
2917
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2918
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2888
2919
|
statements: this.statements.map(node => node.toJSON()),
|
|
2889
2920
|
};
|
|
2890
2921
|
}
|
|
@@ -2895,6 +2926,7 @@ class ERBInNode extends Node {
|
|
|
2895
2926
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2896
2927
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2897
2928
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2929
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2898
2930
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2899
2931
|
return output;
|
|
2900
2932
|
}
|
|
@@ -3042,7 +3074,7 @@ class ParseResult extends Result {
|
|
|
3042
3074
|
}
|
|
3043
3075
|
|
|
3044
3076
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3045
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3077
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/node-type-guards.ts.erb
|
|
3046
3078
|
/**
|
|
3047
3079
|
* Type guard functions for AST nodes.
|
|
3048
3080
|
* These functions provide type checking by combining both instanceof
|
|
@@ -3539,7 +3571,7 @@ function getNodesAfterPosition(nodes, position, inclusive = true) {
|
|
|
3539
3571
|
}
|
|
3540
3572
|
|
|
3541
3573
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3542
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3574
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/visitor.ts.erb
|
|
3543
3575
|
class Visitor {
|
|
3544
3576
|
visit(node) {
|
|
3545
3577
|
if (!node)
|
|
@@ -4530,6 +4562,11 @@ function isFrontmatter(node) {
|
|
|
4530
4562
|
return content.startsWith("---") && /---\s*$/.test(content);
|
|
4531
4563
|
}
|
|
4532
4564
|
|
|
4565
|
+
/**
|
|
4566
|
+
* ASCII whitespace pattern - use instead of \s to preserve Unicode whitespace
|
|
4567
|
+
* characters like NBSP (U+00A0) and full-width space (U+3000)
|
|
4568
|
+
*/
|
|
4569
|
+
const ASCII_WHITESPACE = /[ \t\n\r]+/g;
|
|
4533
4570
|
/**
|
|
4534
4571
|
* Printer traverses the Herb AST using the Visitor pattern
|
|
4535
4572
|
* and emits a formatted string with proper indentation, line breaks, and attribute wrapping.
|
|
@@ -4901,7 +4938,7 @@ class FormatPrinter extends Printer {
|
|
|
4901
4938
|
return true;
|
|
4902
4939
|
}
|
|
4903
4940
|
wouldClassAttributeBeMultiline(content, indentLength) {
|
|
4904
|
-
const normalizedContent = content.replace(
|
|
4941
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4905
4942
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4906
4943
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4907
4944
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4939,12 +4976,12 @@ class FormatPrinter extends Printer {
|
|
|
4939
4976
|
if (/\r?\n/.test(content)) {
|
|
4940
4977
|
const name = attribute.name ? getCombinedAttributeName(attribute.name) : "";
|
|
4941
4978
|
if (name === "class") {
|
|
4942
|
-
const normalizedContent = content.replace(
|
|
4979
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4943
4980
|
return normalizedContent.length > 80;
|
|
4944
4981
|
}
|
|
4945
4982
|
const lines = content.split(/\r?\n/);
|
|
4946
4983
|
if (lines.length > 1) {
|
|
4947
|
-
return lines.slice(1).some(line =>
|
|
4984
|
+
return lines.slice(1).some(line => /^[ \t\n\r]+/.test(line));
|
|
4948
4985
|
}
|
|
4949
4986
|
}
|
|
4950
4987
|
}
|
|
@@ -4952,7 +4989,7 @@ class FormatPrinter extends Printer {
|
|
|
4952
4989
|
});
|
|
4953
4990
|
}
|
|
4954
4991
|
formatClassAttribute(content, name, equals, open_quote, close_quote) {
|
|
4955
|
-
const normalizedContent = content.replace(
|
|
4992
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4956
4993
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4957
4994
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4958
4995
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4981,7 +5018,7 @@ class FormatPrinter extends Printer {
|
|
|
4981
5018
|
}
|
|
4982
5019
|
formatMultilineAttribute(content, name, open_quote, close_quote) {
|
|
4983
5020
|
if (name === 'srcset' || name === 'sizes') {
|
|
4984
|
-
const normalizedContent = content.replace(
|
|
5021
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4985
5022
|
return open_quote + normalizedContent + close_quote;
|
|
4986
5023
|
}
|
|
4987
5024
|
const lines = content.split('\n');
|
|
@@ -5171,7 +5208,7 @@ class FormatPrinter extends Printer {
|
|
|
5171
5208
|
nodesToRender.forEach(child => {
|
|
5172
5209
|
if (isNode(child, HTMLTextNode)) {
|
|
5173
5210
|
if (hasTextFlow) {
|
|
5174
|
-
const normalizedContent = child.content.replace(
|
|
5211
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5175
5212
|
if (normalizedContent && normalizedContent !== ' ') {
|
|
5176
5213
|
this.push(normalizedContent);
|
|
5177
5214
|
}
|
|
@@ -5180,7 +5217,7 @@ class FormatPrinter extends Printer {
|
|
|
5180
5217
|
}
|
|
5181
5218
|
}
|
|
5182
5219
|
else {
|
|
5183
|
-
const normalizedContent = child.content.replace(
|
|
5220
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5184
5221
|
if (shouldPreserveSpaces && normalizedContent) {
|
|
5185
5222
|
this.push(normalizedContent);
|
|
5186
5223
|
}
|
|
@@ -5205,8 +5242,8 @@ class FormatPrinter extends Printer {
|
|
|
5205
5242
|
});
|
|
5206
5243
|
const content = lines.join('');
|
|
5207
5244
|
const inlineContent = shouldPreserveSpaces
|
|
5208
|
-
? (hasTextFlow ? content.replace(
|
|
5209
|
-
: (hasTextFlow ? content.replace(
|
|
5245
|
+
? (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ') : content)
|
|
5246
|
+
: (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ').trim() : content.trim());
|
|
5210
5247
|
if (inlineContent) {
|
|
5211
5248
|
this.pushToLastLine(inlineContent);
|
|
5212
5249
|
}
|
|
@@ -5395,7 +5432,7 @@ class FormatPrinter extends Printer {
|
|
|
5395
5432
|
}
|
|
5396
5433
|
visitHTMLTextNode(node) {
|
|
5397
5434
|
if (this.inlineMode) {
|
|
5398
|
-
const normalizedContent = node.content.replace(
|
|
5435
|
+
const normalizedContent = node.content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
5399
5436
|
if (normalizedContent) {
|
|
5400
5437
|
this.push(normalizedContent);
|
|
5401
5438
|
}
|
|
@@ -5405,7 +5442,7 @@ class FormatPrinter extends Printer {
|
|
|
5405
5442
|
if (!text)
|
|
5406
5443
|
return;
|
|
5407
5444
|
const wrapWidth = this.maxLineLength - this.indent.length;
|
|
5408
|
-
const words = text.split(
|
|
5445
|
+
const words = text.split(/[ \t\n\r]+/);
|
|
5409
5446
|
const lines = [];
|
|
5410
5447
|
let line = "";
|
|
5411
5448
|
for (const word of words) {
|
|
@@ -5914,7 +5951,7 @@ class FormatPrinter extends Printer {
|
|
|
5914
5951
|
wrappedLines: []
|
|
5915
5952
|
};
|
|
5916
5953
|
}
|
|
5917
|
-
const words = restText.split(
|
|
5954
|
+
const words = restText.split(/[ \t\n\r]+/);
|
|
5918
5955
|
let toMerge = punctuation;
|
|
5919
5956
|
let mergedWordCount = 0;
|
|
5920
5957
|
for (const word of words) {
|
|
@@ -6064,7 +6101,7 @@ class FormatPrinter extends Printer {
|
|
|
6064
6101
|
words.push({ word: unit.content, isHerbDisable: unit.isHerbDisable || false });
|
|
6065
6102
|
}
|
|
6066
6103
|
else {
|
|
6067
|
-
const text = unit.content.replace(
|
|
6104
|
+
const text = unit.content.replace(ASCII_WHITESPACE, ' ');
|
|
6068
6105
|
const hasLeadingSpace = text.startsWith(' ');
|
|
6069
6106
|
const hasTrailingSpace = text.endsWith(' ');
|
|
6070
6107
|
const trimmedText = text.trim();
|
|
@@ -6110,7 +6147,7 @@ class FormatPrinter extends Printer {
|
|
|
6110
6147
|
return false;
|
|
6111
6148
|
const firstWord = words[0];
|
|
6112
6149
|
const firstChar = firstWord[0];
|
|
6113
|
-
if (
|
|
6150
|
+
if (' \t\n\r'.includes(firstChar)) {
|
|
6114
6151
|
return false;
|
|
6115
6152
|
}
|
|
6116
6153
|
lastUnit.unit.content += firstWord;
|
|
@@ -6167,7 +6204,7 @@ class FormatPrinter extends Printer {
|
|
|
6167
6204
|
if (hasWhitespaceBetween(children, lastProcessedIndex, currentIndex)) {
|
|
6168
6205
|
return true;
|
|
6169
6206
|
}
|
|
6170
|
-
if (isNode(currentNode, HTMLTextNode) &&
|
|
6207
|
+
if (isNode(currentNode, HTMLTextNode) && /^[ \t\n\r]/.test(currentNode.content)) {
|
|
6171
6208
|
return true;
|
|
6172
6209
|
}
|
|
6173
6210
|
return false;
|
|
@@ -6506,9 +6543,9 @@ class FormatPrinter extends Printer {
|
|
|
6506
6543
|
const shouldPreserveSpaces = hasOnlyTextContent && tagName && isInlineElement(tagName);
|
|
6507
6544
|
for (const child of children) {
|
|
6508
6545
|
if (isNode(child, HTMLTextNode)) {
|
|
6509
|
-
const normalizedContent = child.content.replace(
|
|
6510
|
-
const hasLeadingSpace =
|
|
6511
|
-
const hasTrailingSpace =
|
|
6546
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
6547
|
+
const hasLeadingSpace = /^[ \t\n\r]/.test(child.content);
|
|
6548
|
+
const hasTrailingSpace = /[ \t\n\r]$/.test(child.content);
|
|
6512
6549
|
const trimmedContent = normalizedContent.trim();
|
|
6513
6550
|
if (trimmedContent) {
|
|
6514
6551
|
if (hasLeadingSpace && (result || shouldPreserveSpaces) && !result.endsWith(' ')) {
|
|
@@ -6615,7 +6652,7 @@ class FormatPrinter extends Printer {
|
|
|
6615
6652
|
content += this.reconstructERBNode(child, true);
|
|
6616
6653
|
}
|
|
6617
6654
|
}
|
|
6618
|
-
return content.replace(
|
|
6655
|
+
return content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
6619
6656
|
}
|
|
6620
6657
|
}
|
|
6621
6658
|
|