23
23
* The node that the compiler receives (default: `Node`).
24
24
* @template {CompileResults} [Result=CompileResults]
25
25
* The thing that the compiler yields (default: `CompileResults`).
26
- * @typedef { CompilerClass<Tree, Result> | CompilerFunction<Tree, Result> } Compiler
26
+ * @callback Compiler
27
27
* A **compiler** handles the compiling of a syntax tree to something else
28
- * (in most cases, text).
28
+ * (in most cases, text) (TypeScript type) .
29
29
*
30
30
* It is used in the stringify phase and called with a {@link Node `Node`}
31
31
* and {@link VFile `VFile`} representation of the document to compile.
32
- *
33
- * `Compiler` can be a normal function, in which case it should return the
34
- * textual representation of the given tree (typically `string`).
35
- *
36
- * `Compiler` can also be a constructor function (a function with a `compile`
37
- * field in its `prototype`), in which case it is constructed with `new`.
38
- * Instances must have a `compile` method that is called without arguments
39
- * and typically returns a `string`.
32
+ * It should return the textual representation of the given tree (typically
33
+ * `string`).
40
34
*
41
35
* > 👉 **Note**: unified typically compiles by serializing: most compilers
42
36
* > return `string` (or `Uint8Array`).
50
44
* > {@link CompileResultMap `CompileResultMap`}.
51
45
*
52
46
* [rehype-react]: https://github.com/rehypejs/rehype-react
53
- */
54
-
55
- /**
56
- * @template {Node} [Tree=Node]
57
- * The node that the compiler receives (default: `Node`)
58
- * @template {CompileResults} [Result=CompileResults]
59
- * The thing that the compiler yields (default: `CompileResults`).
60
- * @typedef {({
61
- * prototype: {compile(): Result}
62
- * new (tree: Tree, file: VFile): CompilerClass<Tree, Result>['prototype']
63
- * }) } CompilerClass
64
- * Class to compile trees.
65
- */
66
-
67
- /**
68
- * @template {Node} [Tree=Node]
69
- * The node that the compiler receives (default: `Node`).
70
- * @template {CompileResults} [Result=CompileResults]
71
- * The thing that the compiler yields (default: `CompileResults`).
72
- * @callback CompilerFunction
73
- * Regular function to compile a tree.
74
47
* @param {Tree } tree
75
48
* Tree to compile.
76
49
* @param {VFile } file
83
56
/**
84
57
* @template {Node} [Tree=Node]
85
58
* The node that the parser yields (default: `Node`)
86
- * @typedef { ParserClass<Tree> | ParserFunction<Tree> } Parser
59
+ * @callback Parser
87
60
* A **parser** handles the parsing of text to a syntax tree.
88
61
*
89
62
* It is used in the parse phase and is called with a `string` and
90
63
* {@link VFile `VFile`} of the document to parse.
91
- *
92
- * `Parser` can be a normal function, in which case it must return the syntax
93
- * tree representation of the given file ({@link Node `Node`}).
94
- *
95
- * `Parser` can also be a constructor function (a function with a `parse`
96
- * field in its `prototype`), in which case it is constructed with `new`.
97
- * Instances must have a `parse` method that is called without arguments and
98
- * must return a {@link Node `Node`}.
99
- */
100
-
101
- /**
102
- * @template {Node} [Tree=Node]
103
- * The node that the parser yields (default: `Node`).
104
- * @typedef {({
105
- * prototype: {parse(): Tree}
106
- * new (document: string, file: VFile): ParserClass<Tree>['prototype']
107
- * }) } ParserClass
108
- * Class to parse files.
109
- */
110
-
111
- /**
112
- * @template {Node} [Tree=Node]
113
- * The node that the parser yields (default: `Node`).
114
- * @callback ParserFunction
115
- * Regular function to parse a file.
64
+ * It must return the syntax tree representation of the given file
65
+ * ({@link Node `Node`}).
116
66
* @param {string } document
117
67
* Document to parse.
118
68
* @param {VFile } file
@@ -403,13 +353,11 @@ import {trough} from 'trough'
403
353
import { VFile } from 'vfile'
404
354
import { CallableInstance } from './callable-instance.js'
405
355
406
- // To do: we could drop class support for the parser and compiler,
407
- // we don’t use that anymore?
408
- // Would be less breaking if we do `processor.compiler || processor.Compiler`.
356
+ // To do: next major: drop `Compiler`, `Parser`: prefer lowercase.
409
357
410
358
// To do: we could start yielding `never` in TS when a parser is missing and
411
359
// `parse` is called.
412
- // Currently, we allow directly setting `processor.Parser `, which is untyped.
360
+ // Currently, we allow directly setting `processor.parser `, which is untyped.
413
361
414
362
const own = { } . hasOwnProperty
415
363
@@ -435,8 +383,10 @@ export class Processor extends CallableInstance {
435
383
super ( 'copy' )
436
384
437
385
/**
438
- * Compiler to use.
386
+ * Compiler to use (deprecated) .
439
387
*
388
+ * @deprecated
389
+ * Use `compiler` instead.
440
390
* @type {(
441
391
* Compiler<
442
392
* CompileTree extends undefined ? Node : CompileTree,
@@ -448,8 +398,10 @@ export class Processor extends CallableInstance {
448
398
this . Compiler = undefined
449
399
450
400
/**
451
- * Parser to use.
401
+ * Parser to use (deprecated) .
452
402
*
403
+ * @deprecated
404
+ * Use `parser` instead.
453
405
* @type {(
454
406
* Parser<ParseTree extends undefined ? Node : ParseTree> |
455
407
* undefined
@@ -470,6 +422,19 @@ export class Processor extends CallableInstance {
470
422
*/
471
423
this . attachers = [ ]
472
424
425
+ /**
426
+ * Compiler to use.
427
+ *
428
+ * @type {(
429
+ * Compiler<
430
+ * CompileTree extends undefined ? Node : CompileTree,
431
+ * CompileResult extends undefined ? CompileResults : CompileResult
432
+ * > |
433
+ * undefined
434
+ * )}
435
+ */
436
+ this . compiler = undefined
437
+
473
438
/**
474
439
* Internal state to track where we are while freezing.
475
440
*
@@ -497,6 +462,16 @@ export class Processor extends CallableInstance {
497
462
*/
498
463
this . namespace = { }
499
464
465
+ /**
466
+ * Parser to use.
467
+ *
468
+ * @type {(
469
+ * Parser<ParseTree extends undefined ? Node : ParseTree> |
470
+ * undefined
471
+ * )}
472
+ */
473
+ this . parser = undefined
474
+
500
475
/**
501
476
* Internal list of configured transformers.
502
477
*
@@ -687,26 +662,9 @@ export class Processor extends CallableInstance {
687
662
parse ( file ) {
688
663
this . freeze ( )
689
664
const realFile = vfile ( file )
690
- const Parser = this . Parser
691
- assertParser ( 'parse' , Parser )
692
-
693
- if ( newable ( Parser , 'parse' ) ) {
694
- const ParserClass =
695
- /** @type {ParserClass<ParseTree extends undefined ? Node : ParseTree> } */ (
696
- Parser
697
- )
698
-
699
- const parserInstace = new ParserClass ( String ( realFile ) , realFile )
700
-
701
- return parserInstace . parse ( )
702
- }
703
-
704
- const parserFunction =
705
- /** @type {ParserFunction<ParseTree extends undefined ? Node : ParseTree> } */ (
706
- Parser
707
- )
708
-
709
- return parserFunction ( String ( realFile ) , realFile )
665
+ const parser = this . parser || this . Parser
666
+ assertParser ( 'parse' , parser )
667
+ return parser ( String ( realFile ) , realFile )
710
668
}
711
669
712
670
/**
@@ -755,8 +713,8 @@ export class Processor extends CallableInstance {
755
713
const self = this
756
714
757
715
this . freeze ( )
758
- assertParser ( 'process' , this . Parser )
759
- assertCompiler ( 'process' , this . Compiler )
716
+ assertParser ( 'process' , this . parser || this . Parser )
717
+ assertCompiler ( 'process' , this . compiler || this . Compiler )
760
718
761
719
return done ? executor ( undefined , done ) : new Promise ( executor )
762
720
@@ -854,8 +812,8 @@ export class Processor extends CallableInstance {
854
812
let result
855
813
856
814
this . freeze ( )
857
- assertParser ( 'processSync' , this . Parser )
858
- assertCompiler ( 'processSync' , this . Compiler )
815
+ assertParser ( 'processSync' , this . parser || this . Parser )
816
+ assertCompiler ( 'processSync' , this . compiler || this . Compiler )
859
817
860
818
this . process ( file , realDone )
861
819
assertDone ( 'processSync' , 'process' , complete )
@@ -1036,35 +994,11 @@ export class Processor extends CallableInstance {
1036
994
stringify ( tree , file ) {
1037
995
this . freeze ( )
1038
996
const realFile = vfile ( file )
1039
- const Compiler = this . Compiler
1040
- assertCompiler ( 'stringify' , Compiler )
997
+ const compiler = this . compiler || this . Compiler
998
+ assertCompiler ( 'stringify' , compiler )
1041
999
assertNode ( tree )
1042
1000
1043
- if ( newable ( Compiler , 'compile' ) ) {
1044
- const CompilerClass = /**
1045
- * @type {(
1046
- * CompilerClass<
1047
- * CompileTree extends undefined ? Node : CompileTree,
1048
- * CompileResult extends undefined ? CompileResults : CompileResult
1049
- * >
1050
- * )}
1051
- */ ( Compiler )
1052
-
1053
- const compilerInstace = new CompilerClass ( tree , realFile )
1054
-
1055
- return compilerInstace . compile ( )
1056
- }
1057
-
1058
- const compilerFunction = /**
1059
- * @type {(
1060
- * CompilerFunction<
1061
- * CompileTree extends undefined ? Node : CompileTree,
1062
- * CompileResult extends undefined ? CompileResults : CompileResult
1063
- * >
1064
- * )}
1065
- */ ( Compiler )
1066
-
1067
- return compilerFunction ( tree , realFile )
1001
+ return compiler ( tree , realFile )
1068
1002
}
1069
1003
1070
1004
/**
@@ -1270,45 +1204,6 @@ export class Processor extends CallableInstance {
1270
1204
*/
1271
1205
export const unified = new Processor ( ) . freeze ( )
1272
1206
1273
- /**
1274
- * Check if `value` is a constructor.
1275
- *
1276
- * @param {unknown } value
1277
- * @param {string } name
1278
- * @returns {boolean }
1279
- */
1280
- function newable ( value , name ) {
1281
- const proto =
1282
- // Prototypes are `unknown`.
1283
- // type-coverage:ignore-next-line
1284
- typeof value === 'function' && /** @type {unknown } */ ( value . prototype )
1285
-
1286
- return (
1287
- proto !== null &&
1288
- typeof proto === 'object' &&
1289
- ( keys ( proto ) || name in proto )
1290
- )
1291
- }
1292
-
1293
- /**
1294
- * Check if `value` is an object with keys.
1295
- *
1296
- * @param {object } value
1297
- * @returns {boolean }
1298
- */
1299
- function keys ( value ) {
1300
- /** @type {string } */
1301
- let key
1302
-
1303
- for ( key in value ) {
1304
- if ( own . call ( value , key ) ) {
1305
- return true
1306
- }
1307
- }
1308
-
1309
- return false
1310
- }
1311
-
1312
1207
/**
1313
1208
* Assert a parser is available.
1314
1209
*
@@ -1318,7 +1213,7 @@ function keys(value) {
1318
1213
*/
1319
1214
function assertParser ( name , value ) {
1320
1215
if ( typeof value !== 'function' ) {
1321
- throw new TypeError ( 'Cannot `' + name + '` without `Parser `' )
1216
+ throw new TypeError ( 'Cannot `' + name + '` without `parser `' )
1322
1217
}
1323
1218
}
1324
1219
@@ -1331,7 +1226,7 @@ function assertParser(name, value) {
1331
1226
*/
1332
1227
function assertCompiler ( name , value ) {
1333
1228
if ( typeof value !== 'function' ) {
1334
- throw new TypeError ( 'Cannot `' + name + '` without `Compiler `' )
1229
+ throw new TypeError ( 'Cannot `' + name + '` without `compiler `' )
1335
1230
}
1336
1231
}
1337
1232
0 commit comments