@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.esm.js
CHANGED
|
@@ -64,6 +64,18 @@ function createDedent(options) {
|
|
|
64
64
|
if (escapeSpecialCharacters) {
|
|
65
65
|
result = result.replace(/\\n/g, "\n");
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
// Workaround for Bun issue with Unicode characters
|
|
69
|
+
// https://github.com/oven-sh/bun/issues/8745
|
|
70
|
+
if (typeof Bun !== "undefined") {
|
|
71
|
+
result = result.replace(
|
|
72
|
+
// Matches e.g. \\u{1f60a} or \\u5F1F
|
|
73
|
+
/\\u(?:\{([\da-fA-F]{1,6})\}|([\da-fA-F]{4}))/g, (_, braced, unbraced) => {
|
|
74
|
+
var _ref;
|
|
75
|
+
const hex = (_ref = braced !== null && braced !== void 0 ? braced : unbraced) !== null && _ref !== void 0 ? _ref : "";
|
|
76
|
+
return String.fromCodePoint(parseInt(hex, 16));
|
|
77
|
+
});
|
|
78
|
+
}
|
|
67
79
|
return result;
|
|
68
80
|
}
|
|
69
81
|
}
|
|
@@ -241,7 +253,7 @@ class Token {
|
|
|
241
253
|
}
|
|
242
254
|
|
|
243
255
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
244
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
256
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/errors.ts.erb
|
|
245
257
|
class HerbError {
|
|
246
258
|
type;
|
|
247
259
|
message;
|
|
@@ -806,7 +818,7 @@ function convertToUTF8(string) {
|
|
|
806
818
|
}
|
|
807
819
|
|
|
808
820
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
809
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
821
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/nodes.ts.erb
|
|
810
822
|
class Node {
|
|
811
823
|
type;
|
|
812
824
|
location;
|
|
@@ -1880,6 +1892,7 @@ class ERBIfNode extends Node {
|
|
|
1880
1892
|
tag_opening;
|
|
1881
1893
|
content;
|
|
1882
1894
|
tag_closing;
|
|
1895
|
+
then_keyword;
|
|
1883
1896
|
statements;
|
|
1884
1897
|
subsequent;
|
|
1885
1898
|
end_node;
|
|
@@ -1894,6 +1907,7 @@ class ERBIfNode extends Node {
|
|
|
1894
1907
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
1895
1908
|
content: data.content ? Token.from(data.content) : null,
|
|
1896
1909
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
1910
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
1897
1911
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
1898
1912
|
subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
|
|
1899
1913
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -1904,6 +1918,7 @@ class ERBIfNode extends Node {
|
|
|
1904
1918
|
this.tag_opening = props.tag_opening;
|
|
1905
1919
|
this.content = props.content;
|
|
1906
1920
|
this.tag_closing = props.tag_closing;
|
|
1921
|
+
this.then_keyword = props.then_keyword;
|
|
1907
1922
|
this.statements = props.statements;
|
|
1908
1923
|
this.subsequent = props.subsequent;
|
|
1909
1924
|
this.end_node = props.end_node;
|
|
@@ -1936,6 +1951,7 @@ class ERBIfNode extends Node {
|
|
|
1936
1951
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
1937
1952
|
content: this.content ? this.content.toJSON() : null,
|
|
1938
1953
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
1954
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
1939
1955
|
statements: this.statements.map(node => node.toJSON()),
|
|
1940
1956
|
subsequent: this.subsequent ? this.subsequent.toJSON() : null,
|
|
1941
1957
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -1948,6 +1964,7 @@ class ERBIfNode extends Node {
|
|
|
1948
1964
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
1949
1965
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
1950
1966
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
1967
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
1951
1968
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
1952
1969
|
output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
|
|
1953
1970
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2029,6 +2046,7 @@ class ERBWhenNode extends Node {
|
|
|
2029
2046
|
tag_opening;
|
|
2030
2047
|
content;
|
|
2031
2048
|
tag_closing;
|
|
2049
|
+
then_keyword;
|
|
2032
2050
|
statements;
|
|
2033
2051
|
static get type() {
|
|
2034
2052
|
return "AST_ERB_WHEN_NODE";
|
|
@@ -2041,6 +2059,7 @@ class ERBWhenNode extends Node {
|
|
|
2041
2059
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2042
2060
|
content: data.content ? Token.from(data.content) : null,
|
|
2043
2061
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2062
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2044
2063
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2045
2064
|
});
|
|
2046
2065
|
}
|
|
@@ -2049,6 +2068,7 @@ class ERBWhenNode extends Node {
|
|
|
2049
2068
|
this.tag_opening = props.tag_opening;
|
|
2050
2069
|
this.content = props.content;
|
|
2051
2070
|
this.tag_closing = props.tag_closing;
|
|
2071
|
+
this.then_keyword = props.then_keyword;
|
|
2052
2072
|
this.statements = props.statements;
|
|
2053
2073
|
}
|
|
2054
2074
|
accept(visitor) {
|
|
@@ -2075,6 +2095,7 @@ class ERBWhenNode extends Node {
|
|
|
2075
2095
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2076
2096
|
content: this.content ? this.content.toJSON() : null,
|
|
2077
2097
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2098
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2078
2099
|
statements: this.statements.map(node => node.toJSON()),
|
|
2079
2100
|
};
|
|
2080
2101
|
}
|
|
@@ -2085,6 +2106,7 @@ class ERBWhenNode extends Node {
|
|
|
2085
2106
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2086
2107
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2087
2108
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2109
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2088
2110
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2089
2111
|
return output;
|
|
2090
2112
|
}
|
|
@@ -2703,6 +2725,7 @@ class ERBUnlessNode extends Node {
|
|
|
2703
2725
|
tag_opening;
|
|
2704
2726
|
content;
|
|
2705
2727
|
tag_closing;
|
|
2728
|
+
then_keyword;
|
|
2706
2729
|
statements;
|
|
2707
2730
|
else_clause;
|
|
2708
2731
|
end_node;
|
|
@@ -2717,6 +2740,7 @@ class ERBUnlessNode extends Node {
|
|
|
2717
2740
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2718
2741
|
content: data.content ? Token.from(data.content) : null,
|
|
2719
2742
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2743
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2720
2744
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2721
2745
|
else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
|
|
2722
2746
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -2727,6 +2751,7 @@ class ERBUnlessNode extends Node {
|
|
|
2727
2751
|
this.tag_opening = props.tag_opening;
|
|
2728
2752
|
this.content = props.content;
|
|
2729
2753
|
this.tag_closing = props.tag_closing;
|
|
2754
|
+
this.then_keyword = props.then_keyword;
|
|
2730
2755
|
this.statements = props.statements;
|
|
2731
2756
|
this.else_clause = props.else_clause;
|
|
2732
2757
|
this.end_node = props.end_node;
|
|
@@ -2759,6 +2784,7 @@ class ERBUnlessNode extends Node {
|
|
|
2759
2784
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2760
2785
|
content: this.content ? this.content.toJSON() : null,
|
|
2761
2786
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2787
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2762
2788
|
statements: this.statements.map(node => node.toJSON()),
|
|
2763
2789
|
else_clause: this.else_clause ? this.else_clause.toJSON() : null,
|
|
2764
2790
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -2771,6 +2797,7 @@ class ERBUnlessNode extends Node {
|
|
|
2771
2797
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2772
2798
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2773
2799
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2800
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2774
2801
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
2775
2802
|
output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
|
|
2776
2803
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2837,6 +2864,7 @@ class ERBInNode extends Node {
|
|
|
2837
2864
|
tag_opening;
|
|
2838
2865
|
content;
|
|
2839
2866
|
tag_closing;
|
|
2867
|
+
then_keyword;
|
|
2840
2868
|
statements;
|
|
2841
2869
|
static get type() {
|
|
2842
2870
|
return "AST_ERB_IN_NODE";
|
|
@@ -2849,6 +2877,7 @@ class ERBInNode extends Node {
|
|
|
2849
2877
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2850
2878
|
content: data.content ? Token.from(data.content) : null,
|
|
2851
2879
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2880
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2852
2881
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2853
2882
|
});
|
|
2854
2883
|
}
|
|
@@ -2857,6 +2886,7 @@ class ERBInNode extends Node {
|
|
|
2857
2886
|
this.tag_opening = props.tag_opening;
|
|
2858
2887
|
this.content = props.content;
|
|
2859
2888
|
this.tag_closing = props.tag_closing;
|
|
2889
|
+
this.then_keyword = props.then_keyword;
|
|
2860
2890
|
this.statements = props.statements;
|
|
2861
2891
|
}
|
|
2862
2892
|
accept(visitor) {
|
|
@@ -2883,6 +2913,7 @@ class ERBInNode extends Node {
|
|
|
2883
2913
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2884
2914
|
content: this.content ? this.content.toJSON() : null,
|
|
2885
2915
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2916
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2886
2917
|
statements: this.statements.map(node => node.toJSON()),
|
|
2887
2918
|
};
|
|
2888
2919
|
}
|
|
@@ -2893,6 +2924,7 @@ class ERBInNode extends Node {
|
|
|
2893
2924
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2894
2925
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2895
2926
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2927
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2896
2928
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2897
2929
|
return output;
|
|
2898
2930
|
}
|
|
@@ -3040,7 +3072,7 @@ class ParseResult extends Result {
|
|
|
3040
3072
|
}
|
|
3041
3073
|
|
|
3042
3074
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3043
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3075
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/node-type-guards.ts.erb
|
|
3044
3076
|
/**
|
|
3045
3077
|
* Type guard functions for AST nodes.
|
|
3046
3078
|
* These functions provide type checking by combining both instanceof
|
|
@@ -3537,7 +3569,7 @@ function getNodesAfterPosition(nodes, position, inclusive = true) {
|
|
|
3537
3569
|
}
|
|
3538
3570
|
|
|
3539
3571
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3540
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3572
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/visitor.ts.erb
|
|
3541
3573
|
class Visitor {
|
|
3542
3574
|
visit(node) {
|
|
3543
3575
|
if (!node)
|
|
@@ -4528,6 +4560,11 @@ function isFrontmatter(node) {
|
|
|
4528
4560
|
return content.startsWith("---") && /---\s*$/.test(content);
|
|
4529
4561
|
}
|
|
4530
4562
|
|
|
4563
|
+
/**
|
|
4564
|
+
* ASCII whitespace pattern - use instead of \s to preserve Unicode whitespace
|
|
4565
|
+
* characters like NBSP (U+00A0) and full-width space (U+3000)
|
|
4566
|
+
*/
|
|
4567
|
+
const ASCII_WHITESPACE = /[ \t\n\r]+/g;
|
|
4531
4568
|
/**
|
|
4532
4569
|
* Printer traverses the Herb AST using the Visitor pattern
|
|
4533
4570
|
* and emits a formatted string with proper indentation, line breaks, and attribute wrapping.
|
|
@@ -4899,7 +4936,7 @@ class FormatPrinter extends Printer {
|
|
|
4899
4936
|
return true;
|
|
4900
4937
|
}
|
|
4901
4938
|
wouldClassAttributeBeMultiline(content, indentLength) {
|
|
4902
|
-
const normalizedContent = content.replace(
|
|
4939
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4903
4940
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4904
4941
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4905
4942
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4937,12 +4974,12 @@ class FormatPrinter extends Printer {
|
|
|
4937
4974
|
if (/\r?\n/.test(content)) {
|
|
4938
4975
|
const name = attribute.name ? getCombinedAttributeName(attribute.name) : "";
|
|
4939
4976
|
if (name === "class") {
|
|
4940
|
-
const normalizedContent = content.replace(
|
|
4977
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4941
4978
|
return normalizedContent.length > 80;
|
|
4942
4979
|
}
|
|
4943
4980
|
const lines = content.split(/\r?\n/);
|
|
4944
4981
|
if (lines.length > 1) {
|
|
4945
|
-
return lines.slice(1).some(line =>
|
|
4982
|
+
return lines.slice(1).some(line => /^[ \t\n\r]+/.test(line));
|
|
4946
4983
|
}
|
|
4947
4984
|
}
|
|
4948
4985
|
}
|
|
@@ -4950,7 +4987,7 @@ class FormatPrinter extends Printer {
|
|
|
4950
4987
|
});
|
|
4951
4988
|
}
|
|
4952
4989
|
formatClassAttribute(content, name, equals, open_quote, close_quote) {
|
|
4953
|
-
const normalizedContent = content.replace(
|
|
4990
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4954
4991
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4955
4992
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4956
4993
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4979,7 +5016,7 @@ class FormatPrinter extends Printer {
|
|
|
4979
5016
|
}
|
|
4980
5017
|
formatMultilineAttribute(content, name, open_quote, close_quote) {
|
|
4981
5018
|
if (name === 'srcset' || name === 'sizes') {
|
|
4982
|
-
const normalizedContent = content.replace(
|
|
5019
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4983
5020
|
return open_quote + normalizedContent + close_quote;
|
|
4984
5021
|
}
|
|
4985
5022
|
const lines = content.split('\n');
|
|
@@ -5169,7 +5206,7 @@ class FormatPrinter extends Printer {
|
|
|
5169
5206
|
nodesToRender.forEach(child => {
|
|
5170
5207
|
if (isNode(child, HTMLTextNode)) {
|
|
5171
5208
|
if (hasTextFlow) {
|
|
5172
|
-
const normalizedContent = child.content.replace(
|
|
5209
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5173
5210
|
if (normalizedContent && normalizedContent !== ' ') {
|
|
5174
5211
|
this.push(normalizedContent);
|
|
5175
5212
|
}
|
|
@@ -5178,7 +5215,7 @@ class FormatPrinter extends Printer {
|
|
|
5178
5215
|
}
|
|
5179
5216
|
}
|
|
5180
5217
|
else {
|
|
5181
|
-
const normalizedContent = child.content.replace(
|
|
5218
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5182
5219
|
if (shouldPreserveSpaces && normalizedContent) {
|
|
5183
5220
|
this.push(normalizedContent);
|
|
5184
5221
|
}
|
|
@@ -5203,8 +5240,8 @@ class FormatPrinter extends Printer {
|
|
|
5203
5240
|
});
|
|
5204
5241
|
const content = lines.join('');
|
|
5205
5242
|
const inlineContent = shouldPreserveSpaces
|
|
5206
|
-
? (hasTextFlow ? content.replace(
|
|
5207
|
-
: (hasTextFlow ? content.replace(
|
|
5243
|
+
? (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ') : content)
|
|
5244
|
+
: (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ').trim() : content.trim());
|
|
5208
5245
|
if (inlineContent) {
|
|
5209
5246
|
this.pushToLastLine(inlineContent);
|
|
5210
5247
|
}
|
|
@@ -5393,7 +5430,7 @@ class FormatPrinter extends Printer {
|
|
|
5393
5430
|
}
|
|
5394
5431
|
visitHTMLTextNode(node) {
|
|
5395
5432
|
if (this.inlineMode) {
|
|
5396
|
-
const normalizedContent = node.content.replace(
|
|
5433
|
+
const normalizedContent = node.content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
5397
5434
|
if (normalizedContent) {
|
|
5398
5435
|
this.push(normalizedContent);
|
|
5399
5436
|
}
|
|
@@ -5403,7 +5440,7 @@ class FormatPrinter extends Printer {
|
|
|
5403
5440
|
if (!text)
|
|
5404
5441
|
return;
|
|
5405
5442
|
const wrapWidth = this.maxLineLength - this.indent.length;
|
|
5406
|
-
const words = text.split(
|
|
5443
|
+
const words = text.split(/[ \t\n\r]+/);
|
|
5407
5444
|
const lines = [];
|
|
5408
5445
|
let line = "";
|
|
5409
5446
|
for (const word of words) {
|
|
@@ -5912,7 +5949,7 @@ class FormatPrinter extends Printer {
|
|
|
5912
5949
|
wrappedLines: []
|
|
5913
5950
|
};
|
|
5914
5951
|
}
|
|
5915
|
-
const words = restText.split(
|
|
5952
|
+
const words = restText.split(/[ \t\n\r]+/);
|
|
5916
5953
|
let toMerge = punctuation;
|
|
5917
5954
|
let mergedWordCount = 0;
|
|
5918
5955
|
for (const word of words) {
|
|
@@ -6062,7 +6099,7 @@ class FormatPrinter extends Printer {
|
|
|
6062
6099
|
words.push({ word: unit.content, isHerbDisable: unit.isHerbDisable || false });
|
|
6063
6100
|
}
|
|
6064
6101
|
else {
|
|
6065
|
-
const text = unit.content.replace(
|
|
6102
|
+
const text = unit.content.replace(ASCII_WHITESPACE, ' ');
|
|
6066
6103
|
const hasLeadingSpace = text.startsWith(' ');
|
|
6067
6104
|
const hasTrailingSpace = text.endsWith(' ');
|
|
6068
6105
|
const trimmedText = text.trim();
|
|
@@ -6108,7 +6145,7 @@ class FormatPrinter extends Printer {
|
|
|
6108
6145
|
return false;
|
|
6109
6146
|
const firstWord = words[0];
|
|
6110
6147
|
const firstChar = firstWord[0];
|
|
6111
|
-
if (
|
|
6148
|
+
if (' \t\n\r'.includes(firstChar)) {
|
|
6112
6149
|
return false;
|
|
6113
6150
|
}
|
|
6114
6151
|
lastUnit.unit.content += firstWord;
|
|
@@ -6165,7 +6202,7 @@ class FormatPrinter extends Printer {
|
|
|
6165
6202
|
if (hasWhitespaceBetween(children, lastProcessedIndex, currentIndex)) {
|
|
6166
6203
|
return true;
|
|
6167
6204
|
}
|
|
6168
|
-
if (isNode(currentNode, HTMLTextNode) &&
|
|
6205
|
+
if (isNode(currentNode, HTMLTextNode) && /^[ \t\n\r]/.test(currentNode.content)) {
|
|
6169
6206
|
return true;
|
|
6170
6207
|
}
|
|
6171
6208
|
return false;
|
|
@@ -6504,9 +6541,9 @@ class FormatPrinter extends Printer {
|
|
|
6504
6541
|
const shouldPreserveSpaces = hasOnlyTextContent && tagName && isInlineElement(tagName);
|
|
6505
6542
|
for (const child of children) {
|
|
6506
6543
|
if (isNode(child, HTMLTextNode)) {
|
|
6507
|
-
const normalizedContent = child.content.replace(
|
|
6508
|
-
const hasLeadingSpace =
|
|
6509
|
-
const hasTrailingSpace =
|
|
6544
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
6545
|
+
const hasLeadingSpace = /^[ \t\n\r]/.test(child.content);
|
|
6546
|
+
const hasTrailingSpace = /[ \t\n\r]$/.test(child.content);
|
|
6510
6547
|
const trimmedContent = normalizedContent.trim();
|
|
6511
6548
|
if (trimmedContent) {
|
|
6512
6549
|
if (hasLeadingSpace && (result || shouldPreserveSpaces) && !result.endsWith(' ')) {
|
|
@@ -6613,7 +6650,7 @@ class FormatPrinter extends Printer {
|
|
|
6613
6650
|
content += this.reconstructERBNode(child, true);
|
|
6614
6651
|
}
|
|
6615
6652
|
}
|
|
6616
|
-
return content.replace(
|
|
6653
|
+
return content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
6617
6654
|
}
|
|
6618
6655
|
}
|
|
6619
6656
|
|