@@ -10,7 +10,16 @@ import type { IMdxVFile } from "./types"
10
10
import type { Options , toc } from "mdast-util-toc"
11
11
import type { visit } from "unist-util-visit"
12
12
13
- type TocNodeType = BlockContent | DefinitionContent | ListItem
13
+ interface ITocNodeEntry {
14
+ url ?: string
15
+ title ?: string
16
+ }
17
+
18
+ type TocNodeType =
19
+ | ITocNodeEntry
20
+ | {
21
+ items : Array < TocNodeType >
22
+ }
14
23
15
24
interface IRemarkTocOptions {
16
25
maxDepth ?: Options [ "maxDepth" ]
@@ -25,33 +34,50 @@ const remarkInferTocMeta: Plugin<[IRemarkTocOptions]> = options => {
25
34
}
26
35
27
36
const processToC = (
28
- node : TocNodeType ,
29
- current : Partial < TocNodeType >
30
- ) : Partial < TocNodeType > => {
37
+ node : BlockContent | DefinitionContent | ListItem | null ,
38
+ current : TocNodeType
39
+ ) : TocNodeType => {
31
40
if ( ! node ) {
32
41
return { }
33
- } else if ( node . type === `paragraph` ) {
34
- visit ( node , item => {
35
- if ( item . type === `link` ) {
36
- current . url = item . url
37
- }
38
- if ( item . type === `text` ) {
39
- current . title = item . value
40
- }
41
- } )
42
- return current
43
- } else if ( Array . isArray ( node . children ) ) {
44
- if ( node . type === `list` ) {
45
- current . items = node . children . map ( i => processToC ( i , { } ) )
42
+ }
43
+
44
+ switch ( node . type ) {
45
+ case `paragraph` : {
46
+ const typedCurrent = current as ITocNodeEntry
47
+
48
+ visit ( node , item => {
49
+ if ( item . type === `link` ) {
50
+ typedCurrent . url = item . url
51
+ }
52
+ if ( item . type === `text` ) {
53
+ typedCurrent . title = item . value
54
+ }
55
+ } )
56
+
46
57
return current
47
- } else if ( node . type === `listItem` ) {
48
- const heading = processToC ( node . children [ 0 ] , { } )
49
- if ( node . children . length > 1 ) {
50
- processToC ( node . children [ 1 ] , heading )
58
+ }
59
+
60
+ case `list` : {
61
+ const typedCurrent = current as { items : Array < TocNodeType > }
62
+
63
+ typedCurrent . items = node . children . map ( item => processToC ( item , { } ) )
64
+
65
+ return typedCurrent
66
+ }
67
+
68
+ case `listItem` : {
69
+ if ( node . children . length ) {
70
+ const heading = processToC ( node . children [ 0 ] , { } )
71
+
72
+ if ( node . children . length > 1 ) {
73
+ processToC ( node . children [ 1 ] , heading )
74
+ }
75
+
76
+ return heading
51
77
}
52
- return heading
53
78
}
54
79
}
80
+
55
81
return { }
56
82
}
57
83
@@ -62,7 +88,7 @@ const remarkInferTocMeta: Plugin<[IRemarkTocOptions]> = options => {
62
88
mdxFile . data . meta = { }
63
89
}
64
90
65
- mdxFile . data . meta . toc = processToC ( generatedToC . map as TocNodeType , { } )
91
+ mdxFile . data . meta . toc = processToC ( generatedToC . map , { } )
66
92
}
67
93
}
68
94
0 commit comments