1
+ import * as Walker from 'zimmerframe' ;
2
+ import type { TsEstree } from './js/ts-estree.ts' ;
1
3
import { Document , Element , type ChildNode } from 'domhandler' ;
2
4
import { ElementType , parseDocument } from 'htmlparser2' ;
3
5
import serializeDom from 'dom-serializer' ;
@@ -11,21 +13,10 @@ import {
11
13
type ChildNode as CssChildNode
12
14
} from 'postcss' ;
13
15
import * as fleece from 'silver-fleece' ;
14
- import * as Walker from 'zimmerframe' ;
15
- import type { TsEstree } from './ts-estree.ts' ;
16
- import { guessIndentString , guessQuoteStyle } from './utils.ts' ;
17
16
import { print as esrapPrint } from 'esrap' ;
18
17
import * as acorn from 'acorn' ;
19
18
import { tsPlugin } from '@sveltejs/acorn-typescript' ;
20
19
21
- /**
22
- * Most of the AST tooling is pretty big in bundle size and bundling takes forever.
23
- * Nevertheless bundling of these tools seems smart, as they add many dependencies to each install.
24
- * In order to avoid long bundling during development, all of the AST tools have been extracted
25
- * into this separate package and are bundled only here. This package has been marked as external
26
- * and will not be bundled into all other projects / bundles.
27
- */
28
-
29
20
export {
30
21
// html
31
22
Document as HtmlDocument ,
@@ -179,3 +170,73 @@ export function serializeJson(originalInput: string, data: unknown): string {
179
170
180
171
return fleece . stringify ( data , { spaces } ) ;
181
172
}
173
+
174
+ // Sourced from `golden-fleece`
175
+ // https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302
176
+ export function guessIndentString ( str : string | undefined ) : string {
177
+ if ( ! str ) return '\t' ;
178
+
179
+ const lines = str . split ( '\n' ) ;
180
+
181
+ let tabs = 0 ;
182
+ let spaces = 0 ;
183
+ let minSpaces = 8 ;
184
+
185
+ lines . forEach ( ( line ) => {
186
+ const match = / ^ (?: + | \t + ) / . exec ( line ) ;
187
+ if ( ! match ) return ;
188
+
189
+ const whitespace = match [ 0 ] ;
190
+ if ( whitespace . length === line . length ) return ;
191
+
192
+ if ( whitespace [ 0 ] === '\t' ) {
193
+ tabs += 1 ;
194
+ } else {
195
+ spaces += 1 ;
196
+ if ( whitespace . length > 1 && whitespace . length < minSpaces ) {
197
+ minSpaces = whitespace . length ;
198
+ }
199
+ }
200
+ } ) ;
201
+
202
+ if ( spaces > tabs ) {
203
+ let result = '' ;
204
+ while ( minSpaces -- ) result += ' ' ;
205
+ return result ;
206
+ } else {
207
+ return '\t' ;
208
+ }
209
+ }
210
+
211
+ export function guessQuoteStyle ( ast : TsEstree . Node ) : 'single' | 'double' | undefined {
212
+ let singleCount = 0 ;
213
+ let doubleCount = 0 ;
214
+
215
+ Walker . walk ( ast , null , {
216
+ Literal ( node ) {
217
+ if ( node . raw && node . raw . length >= 2 ) {
218
+ // we have at least two characters in the raw string that could represent both quotes
219
+ const quotes = [ node . raw [ 0 ] , node . raw [ node . raw . length - 1 ] ] ;
220
+ for ( const quote of quotes ) {
221
+ switch ( quote ) {
222
+ case "'" :
223
+ singleCount ++ ;
224
+ break ;
225
+ case '"' :
226
+ doubleCount ++ ;
227
+ break ;
228
+ default :
229
+ break ;
230
+ }
231
+ }
232
+ }
233
+ }
234
+ } ) ;
235
+
236
+ if ( singleCount === 0 && doubleCount === 0 ) {
237
+ // new file or file without any quotes
238
+ return undefined ;
239
+ }
240
+
241
+ return singleCount > doubleCount ? 'single' : 'double' ;
242
+ }
0 commit comments