1
1
/**
2
- * @import {Nodes, RootContent, Root} from 'hast'
2
+ * @import {Options} from 'hast-util-format'
3
+ * @import {Root} from 'hast'
3
4
*/
4
5
5
- /**
6
- * @typedef Options
7
- * Configuration.
8
- * @property {Array<string> | null | undefined } [blanks=[]]
9
- * List of tag names to join with a blank line (default: `[]`); these tags,
10
- * when next to each other, are joined by a blank line (`\n\n`); for example,
11
- * when `['head', 'body']` is given, a blank line is added between these two.
12
- * @property {number | string | null | undefined } [indent=2]
13
- * Indentation per level (default: `2`); when number, uses that amount of
14
- * spaces; when `string`, uses that per indentation level.
15
- * @property {boolean | null | undefined } [indentInitial=true]
16
- * Whether to indent the first level (default: `true`); this is usually the
17
- * `<html>`, thus not indenting `head` and `body`.
18
- */
19
-
20
- import { embedded } from 'hast-util-embedded'
21
- import { isElement } from 'hast-util-is-element'
22
- import { phrasing } from 'hast-util-phrasing'
23
- import { whitespace } from 'hast-util-whitespace'
24
- import { whitespaceSensitiveTagNames } from 'html-whitespace-sensitive-tag-names'
25
- import rehypeMinifyWhitespace from 'rehype-minify-whitespace'
26
- import { SKIP , visitParents } from 'unist-util-visit-parents'
27
-
28
- /** @type {Options } */
29
- const emptyOptions = { }
30
- const transformWhitespace = rehypeMinifyWhitespace ( { newlines : true } )
6
+ import { format } from 'hast-util-format'
31
7
32
8
/**
33
9
* Format whitespace in HTML.
@@ -38,19 +14,6 @@ const transformWhitespace = rehypeMinifyWhitespace({newlines: true})
38
14
* Transform.
39
15
*/
40
16
export default function rehypeFormat ( options ) {
41
- const settings = options || emptyOptions
42
- let indent = settings . indent || 2
43
- let indentInitial = settings . indentInitial
44
-
45
- if ( typeof indent === 'number' ) {
46
- indent = ' ' . repeat ( indent )
47
- }
48
-
49
- // Default to indenting the initial level.
50
- if ( indentInitial === null || indentInitial === undefined ) {
51
- indentInitial = true
52
- }
53
-
54
17
/**
55
18
* Transform.
56
19
*
@@ -60,150 +23,6 @@ export default function rehypeFormat(options) {
60
23
* Nothing.
61
24
*/
62
25
return function ( tree ) {
63
- /** @type {boolean | undefined } */
64
- let head
65
-
66
- transformWhitespace ( tree )
67
-
68
- // eslint-disable-next-line complexity
69
- visitParents ( tree , function ( node , parents ) {
70
- let index = - 1
71
-
72
- if ( ! ( 'children' in node ) ) {
73
- return
74
- }
75
-
76
- if ( isElement ( node , 'head' ) ) {
77
- head = true
78
- }
79
-
80
- if ( head && isElement ( node , 'body' ) ) {
81
- head = undefined
82
- }
83
-
84
- if ( isElement ( node , whitespaceSensitiveTagNames ) ) {
85
- return SKIP
86
- }
87
-
88
- const children = node . children
89
- let level = parents . length
90
-
91
- // Don’t indent content of whitespace-sensitive nodes / inlines.
92
- if ( children . length === 0 || ! padding ( node , head ) ) {
93
- return
94
- }
95
-
96
- if ( ! indentInitial ) {
97
- level --
98
- }
99
-
100
- /** @type {boolean | undefined } */
101
- let eol
102
-
103
- // Indent newlines in `text`.
104
- while ( ++ index < children . length ) {
105
- const child = children [ index ]
106
-
107
- if ( child . type === 'text' || child . type === 'comment' ) {
108
- if ( child . value . includes ( '\n' ) ) {
109
- eol = true
110
- }
111
-
112
- child . value = child . value . replace (
113
- / * \n / g,
114
- '$&' + String ( indent ) . repeat ( level )
115
- )
116
- }
117
- }
118
-
119
- /** @type {Array<RootContent> } */
120
- const result = [ ]
121
- /** @type {RootContent | undefined } */
122
- let previous
123
-
124
- index = - 1
125
-
126
- while ( ++ index < children . length ) {
127
- const child = children [ index ]
128
-
129
- if ( padding ( child , head ) || ( eol && ! index ) ) {
130
- addBreak ( result , level , child )
131
- eol = true
132
- }
133
-
134
- previous = child
135
- result . push ( child )
136
- }
137
-
138
- if ( previous && ( eol || padding ( previous , head ) ) ) {
139
- // Ignore trailing whitespace (if that already existed), as we’ll add
140
- // properly indented whitespace.
141
- if ( whitespace ( previous ) ) {
142
- result . pop ( )
143
- previous = result [ result . length - 1 ]
144
- }
145
-
146
- addBreak ( result , level - 1 )
147
- }
148
-
149
- node . children = result
150
- } )
151
- }
152
-
153
- /**
154
- * @param {Array<RootContent> } list
155
- * Nodes.
156
- * @param {number } level
157
- * Indentation level.
158
- * @param {RootContent | undefined } [next]
159
- * Next node.
160
- * @returns {undefined }
161
- * Nothing.
162
- */
163
- function addBreak ( list , level , next ) {
164
- const tail = list [ list . length - 1 ]
165
- const previous = tail && whitespace ( tail ) ? list [ list . length - 2 ] : tail
166
- const replace =
167
- ( blank ( previous ) && blank ( next ) ? '\n\n' : '\n' ) +
168
- String ( indent ) . repeat ( Math . max ( level , 0 ) )
169
-
170
- if ( tail && tail . type === 'text' ) {
171
- tail . value = whitespace ( tail ) ? replace : tail . value + replace
172
- } else {
173
- list . push ( { type : 'text' , value : replace } )
174
- }
26
+ format ( tree , options )
175
27
}
176
-
177
- /**
178
- * @param {Nodes | undefined } node
179
- * Node.
180
- * @returns {boolean }
181
- * Whether `node` is a blank.
182
- */
183
- function blank ( node ) {
184
- return Boolean (
185
- node &&
186
- node . type === 'element' &&
187
- settings . blanks &&
188
- settings . blanks . length > 0 &&
189
- settings . blanks . includes ( node . tagName )
190
- )
191
- }
192
- }
193
-
194
- /**
195
- * @param {Nodes } node
196
- * Node.
197
- * @param {boolean | undefined } head
198
- * Whether the node is in `head`.
199
- * @returns {boolean }
200
- * Whether `node` should be padded.
201
- */
202
- function padding ( node , head ) {
203
- return (
204
- node . type === 'root' ||
205
- ( node . type === 'element'
206
- ? head || isElement ( node , 'script' ) || embedded ( node ) || ! phrasing ( node )
207
- : false )
208
- )
209
28
}
0 commit comments