@@ -140,6 +140,13 @@ export const toMap = (config: Properties): Map<string, string> => {
140
140
return result
141
141
}
142
142
143
+ /**
144
+ * Format key-value pair as a single line.
145
+ *
146
+ * @param key Key, can be empty string.
147
+ * @param value Value, can be empty string.
148
+ * @param sep Separator, cannot be empty. Valid chars are ` :=`.
149
+ */
143
150
const formatLine = ( key : string , value : string , sep : string ) =>
144
151
`${ escapeKey ( key ) } ${ sep } ${ escapeValue ( value ) } `
145
152
@@ -199,16 +206,21 @@ export const remove = (config: Properties, key: string): void =>
199
206
*
200
207
* @param lines Lines to iterate over.
201
208
*/
202
- function * chars ( lines : string [ ] ) : Generator < { char : string ; line : number } > {
209
+ function * chars (
210
+ lines : string [ ]
211
+ ) : Generator < { char : string ; lineNumber : number } > {
203
212
for ( let i = 0 ; i < lines . length ; i ++ ) {
204
213
const line = lines [ i ]
205
214
for ( const char of line ) {
206
- yield { char, line : i }
215
+ yield { char, lineNumber : i }
207
216
}
208
- yield { char : 'EOL' , line : i }
217
+ yield { char : 'EOL' , lineNumber : i }
209
218
}
210
219
}
211
220
221
+ /**
222
+ * State for a simple state-machine inside listPairs.
223
+ */
212
224
enum State {
213
225
START ,
214
226
COMMENT ,
@@ -217,35 +229,44 @@ enum State {
217
229
VALUE
218
230
}
219
231
232
+ /**
233
+ * Create empty START state.
234
+ */
235
+ const newState = ( ) : {
236
+ state : State
237
+ start : number
238
+ key : string
239
+ sep : string
240
+ value : string
241
+ skipSpace : boolean
242
+ escapedNext : boolean
243
+ unicode ?: string
244
+ } => ( {
245
+ state : State . START ,
246
+ start : - 1 ,
247
+ key : '' ,
248
+ sep : '' ,
249
+ value : '' ,
250
+ skipSpace : true ,
251
+ escapedNext : false
252
+ } )
253
+
254
+ /**
255
+ * Parse and iterate over key-pairs.
256
+ *
257
+ * @param lines Lines to parse.
258
+ * @return Parsed and unescaped key-value pairs.
259
+ */
220
260
function * listPairs ( lines : string [ ] ) : Generator < {
221
261
start : number
222
262
len : number
223
263
sep : string
224
264
key : string
225
265
value : string
226
266
} > {
227
- const newState = ( ) : {
228
- state : State
229
- start : number
230
- key : string
231
- sep : string
232
- value : string
233
- skipSpace : boolean
234
- escapedNext : boolean
235
- unicode ?: string
236
- } => ( {
237
- state : State . START ,
238
- start : - 1 ,
239
- key : '' ,
240
- sep : '' ,
241
- value : '' ,
242
- skipSpace : true ,
243
- escapedNext : false
244
- } )
245
-
246
267
let state = newState ( )
247
268
248
- for ( const { char, line } of chars ( lines ) ) {
269
+ for ( const { char, lineNumber } of chars ( lines ) ) {
249
270
// Simply ignore spaces
250
271
if ( state . skipSpace && char === ' ' ) {
251
272
continue
@@ -256,7 +277,7 @@ function* listPairs(lines: string[]): Generator<{
256
277
if ( state . unicode ) {
257
278
// Handle incomplete sequence
258
279
if ( char === 'EOL' ) {
259
- throw new Error ( `Invalid unicode sequence at line ${ line } ` )
280
+ throw new Error ( `Invalid unicode sequence at line ${ lineNumber } ` )
260
281
}
261
282
262
283
// Append and consume until it has correct length
@@ -274,11 +295,11 @@ function* listPairs(lines: string[]): Generator<{
274
295
case '#' :
275
296
case '!' :
276
297
state . state = State . COMMENT
277
- state . start = line
298
+ state . start = lineNumber
278
299
break
279
300
default :
280
301
state . state = State . KEY
281
- state . start = line
302
+ state . start = lineNumber
282
303
break
283
304
}
284
305
}
@@ -295,7 +316,7 @@ function* listPairs(lines: string[]): Generator<{
295
316
if ( state . state === State . KEY ) {
296
317
// Special unicode handling
297
318
if ( state . unicode ) {
298
- state . key += parseUnicode ( state . unicode , line )
319
+ state . key += parseUnicode ( state . unicode , lineNumber )
299
320
state . unicode = undefined
300
321
continue
301
322
}
@@ -308,7 +329,7 @@ function* listPairs(lines: string[]): Generator<{
308
329
state . skipSpace = true
309
330
} else {
310
331
// Value-less key
311
- yield { ...state , len : line - state . start + 1 }
332
+ yield { ...state , len : lineNumber - state . start + 1 }
312
333
state = newState ( )
313
334
}
314
335
break
@@ -358,7 +379,7 @@ function* listPairs(lines: string[]): Generator<{
358
379
switch ( char ) {
359
380
case 'EOL' :
360
381
// Value-less key
361
- yield { ...state , len : line - state . start + 1 }
382
+ yield { ...state , len : lineNumber - state . start + 1 }
362
383
state = newState ( )
363
384
break
364
385
case ' ' :
@@ -386,7 +407,7 @@ function* listPairs(lines: string[]): Generator<{
386
407
if ( state . state === State . VALUE ) {
387
408
// Special unicode handling
388
409
if ( state . unicode ) {
389
- state . value += parseUnicode ( state . unicode , line )
410
+ state . value += parseUnicode ( state . unicode , lineNumber )
390
411
state . unicode = undefined
391
412
continue
392
413
}
@@ -399,7 +420,7 @@ function* listPairs(lines: string[]): Generator<{
399
420
state . skipSpace = true
400
421
} else {
401
422
// Value end
402
- yield { ...state , len : line - state . start + 1 }
423
+ yield { ...state , len : lineNumber - state . start + 1 }
403
424
state = newState ( )
404
425
}
405
426
break
0 commit comments