@@ -9,19 +9,28 @@ var splice = [].splice
9
9
// Search `node` with `options` and invoke `callback`.
10
10
function headingRange ( node , options , callback ) {
11
11
var test = options
12
- var ignoreFinalDefinitions = false
12
+ var children = node . children
13
+ var index = - 1
14
+ var ignoreFinalDefinitions
15
+ var depth
16
+ var start
17
+ var end
18
+ var nodes
19
+ var result
20
+ var child
13
21
14
22
// Object, not regex.
15
23
if ( test && typeof test === 'object' && ! ( 'exec' in test ) ) {
16
- ignoreFinalDefinitions = test . ignoreFinalDefinitions === true
24
+ ignoreFinalDefinitions = test . ignoreFinalDefinitions
17
25
test = test . test
18
26
}
19
27
28
+ // Transform a string into an applicable expression.
20
29
if ( typeof test === 'string' ) {
21
- test = toExpression ( test )
30
+ test = new RegExp ( '^(' + test + ')$' , 'i' )
22
31
}
23
32
24
- // Regex
33
+ // Regex.
25
34
if ( test && 'exec' in test ) {
26
35
test = wrapExpression ( test )
27
36
}
@@ -34,48 +43,32 @@ function headingRange(node, options, callback) {
34
43
)
35
44
}
36
45
37
- search ( node , test , ignoreFinalDefinitions , callback )
38
- }
39
-
40
- // Search a node for heading range.
41
- function search ( root , test , skip , callback ) {
42
- var index = - 1
43
- var children = root . children
44
- var length = children . length
45
- var depth = null
46
- var start = null
47
- var end = null
48
- var nodes
49
- var clean
50
- var child
51
-
52
- while ( ++ index < length ) {
46
+ // Find the range.
47
+ while ( ++ index < children . length ) {
53
48
child = children [ index ]
54
49
55
- if ( closing ( child , depth ) ) {
56
- end = index
57
- break
58
- }
50
+ if ( child . type === 'heading' ) {
51
+ if ( depth && child . depth <= depth ) {
52
+ end = index
53
+ break
54
+ }
59
55
60
- if ( opening ( child , depth , test ) ) {
61
- start = index
62
- depth = child . depth
56
+ if ( ! depth && test ( toString ( child ) , child ) ) {
57
+ depth = child . depth
58
+ start = index
59
+ // Assume no end heading is found.
60
+ end = children . length
61
+ }
63
62
}
64
63
}
65
64
66
- if ( start !== null ) {
67
- if ( end === null ) {
68
- end = length
69
- }
70
-
71
- if ( skip ) {
72
- while ( end > start ) {
73
- child = children [ end - 1 ]
74
-
75
- if ( ! definition ( child ) ) {
76
- break
77
- }
78
-
65
+ // When we have a starting heading.
66
+ if ( depth ) {
67
+ if ( ignoreFinalDefinitions ) {
68
+ while (
69
+ children [ end - 1 ] . type === 'definition' ||
70
+ children [ end - 1 ] . type === 'footnoteDefinition'
71
+ ) {
79
72
end --
80
73
}
81
74
}
@@ -85,35 +78,27 @@ function search(root, test, skip, callback) {
85
78
children . slice ( start + 1 , end ) ,
86
79
children [ end ] ,
87
80
{
88
- parent : root ,
81
+ parent : node ,
89
82
start : start ,
90
83
end : children [ end ] ? end : null
91
84
}
92
85
)
93
86
94
- clean = [ ]
95
- index = - 1
96
- length = nodes && nodes . length
87
+ if ( nodes ) {
88
+ // Ensure no empty nodes are inserted.
89
+ // This could be the case if `end` is in `nodes` but no `end` node exists.
90
+ result = [ ]
91
+ index = - 1
97
92
98
- // Ensure no empty nodes are inserted. This could be the case if `end` is
99
- // in `nodes` but no `end` node exists.
100
- while ( ++ index < length ) {
101
- if ( nodes [ index ] ) {
102
- clean . push ( nodes [ index ] )
93
+ while ( ++ index < nodes . length ) {
94
+ if ( nodes [ index ] ) result . push ( nodes [ index ] )
103
95
}
104
- }
105
96
106
- if ( nodes ) {
107
- splice . apply ( children , [ start , end - start + 1 ] . concat ( clean ) )
97
+ splice . apply ( children , [ start , end - start + 1 ] . concat ( result ) )
108
98
}
109
99
}
110
100
}
111
101
112
- // Transform a string into an applicable expression.
113
- function toExpression ( value ) {
114
- return new RegExp ( '^(' + value + ')$' , 'i' )
115
- }
116
-
117
102
// Wrap an expression into an assertion function.
118
103
function wrapExpression ( expression ) {
119
104
return assertion
@@ -123,22 +108,3 @@ function wrapExpression(expression) {
123
108
return expression . test ( value )
124
109
}
125
110
}
126
-
127
- // Check if `node` is a heading.
128
- function heading ( node ) {
129
- return node && node . type === 'heading'
130
- }
131
-
132
- // Check if `node` is the main heading.
133
- function opening ( node , depth , test ) {
134
- return depth === null && heading ( node ) && test ( toString ( node ) , node )
135
- }
136
-
137
- // Check if `node` is the next heading.
138
- function closing ( node , depth ) {
139
- return depth && heading ( node ) && node . depth <= depth
140
- }
141
-
142
- function definition ( node ) {
143
- return node . type === 'definition' || node . type === 'footnoteDefinition'
144
- }
0 commit comments