@@ -27,7 +27,7 @@ function parseMarkdown(text: string): Token[] {
2727 const line = lines [ i ]
2828
2929 // Skip blank lines
30- if ( line . trim ( ) === '' ) {
30+ if ( line === undefined || line . trim ( ) === '' ) {
3131 i ++
3232 continue
3333 }
@@ -36,9 +36,13 @@ function parseMarkdown(text: string): Token[] {
3636 if ( line . startsWith ( '```' ) ) {
3737 const language = line . slice ( 3 ) . trim ( ) || undefined
3838 i ++
39- const codeLines = [ ]
40- while ( i < lines . length && ! lines [ i ] . startsWith ( '```' ) ) {
41- codeLines . push ( lines [ i ] )
39+ const codeLines : string [ ] = [ ]
40+ while ( i < lines . length && ! lines [ i ] ?. startsWith ( '```' ) ) {
41+ const currentLine = lines [ i ]
42+ if ( currentLine === undefined ) {
43+ throw new Error ( `Line is undefined at index ${ i } .` )
44+ }
45+ codeLines . push ( currentLine )
4246 i ++
4347 }
4448 i ++ // skip the closing ```
@@ -48,7 +52,10 @@ function parseMarkdown(text: string): Token[] {
4852
4953 // Heading
5054 const headingMatch = / ^ ( # { 1 , 6 } ) \s + ( .* ) / . exec ( line )
51- if ( headingMatch ) {
55+ if ( headingMatch !== null ) {
56+ if ( ! ( 1 in headingMatch ) || ! ( 2 in headingMatch ) ) {
57+ throw new Error ( 'Missing entries in regex matches' )
58+ }
5259 const level = headingMatch [ 1 ] . length
5360 tokens . push ( {
5461 type : 'heading' ,
@@ -61,7 +68,10 @@ function parseMarkdown(text: string): Token[] {
6168
6269 // List (ordered or unordered)
6370 const listMatch = / ^ ( \s * ) ( [ - * + ] | \d + \. ) \s + ( .* ) / . exec ( line )
64- if ( listMatch ) {
71+ if ( listMatch !== null ) {
72+ if ( ! ( 1 in listMatch ) || ! ( 2 in listMatch ) ) {
73+ throw new Error ( 'Missing entries in regex matches' )
74+ }
6575 const baseIndent = listMatch [ 1 ] . length
6676 const ordered = / ^ \d + \. / . test ( listMatch [ 2 ] )
6777 const [ items , newIndex ] = parseList ( lines , i , baseIndent )
@@ -72,9 +82,13 @@ function parseMarkdown(text: string): Token[] {
7282
7383 // Blockquote
7484 if ( line . startsWith ( '>' ) ) {
75- const quoteLines = [ ]
76- while ( i < lines . length && lines [ i ] . startsWith ( '>' ) ) {
77- quoteLines . push ( lines [ i ] . replace ( / ^ > \s ? / , '' ) )
85+ const quoteLines : string [ ] = [ ]
86+ while ( i < lines . length && lines [ i ] ?. startsWith ( '>' ) ) {
87+ const line = lines [ i ]
88+ if ( line === undefined ) {
89+ throw new Error ( `Index ${ i } not found in lines` )
90+ }
91+ quoteLines . push ( line . replace ( / ^ > \s ? / , '' ) )
7892 i ++
7993 }
8094 tokens . push ( {
@@ -85,9 +99,13 @@ function parseMarkdown(text: string): Token[] {
8599 }
86100
87101 // Paragraph
88- const paraLines = [ ]
89- while ( i < lines . length && lines [ i ] . trim ( ) !== '' ) {
90- paraLines . push ( lines [ i ] )
102+ const paraLines : string [ ] = [ ]
103+ while ( i < lines . length && lines [ i ] ?. trim ( ) !== '' ) {
104+ const line = lines [ i ]
105+ if ( line === undefined ) {
106+ throw new Error ( `Index ${ i } not found in lines` )
107+ }
108+ paraLines . push ( line )
91109 i ++
92110 }
93111 tokens . push ( {
@@ -104,16 +122,18 @@ function parseList(lines: string[], start: number, baseIndent: number): [Token[]
104122 let i = start
105123
106124 while ( i < lines . length ) {
125+ const line = lines [ i ]
126+
107127 // End of list if blank line or no more lines
108- if ( lines [ i ] . trim ( ) === '' ) {
128+ if ( line === undefined || line . trim ( ) === '' ) {
109129 i ++
110130 continue
111131 }
112132
113133 // This matches a new top-level bullet/number for the list
114- const match = / ^ ( \s * ) ( [ - * + ] | \d + \. ) \s + ( .* ) / . exec ( lines [ i ] )
134+ const match = / ^ ( \s * ) ( [ - * + ] | \d + \. ) \s + ( .* ) / . exec ( line )
115135 // If we don't find a bullet/number at the same indent, break out
116- if ( ! match || match [ 1 ] . length !== baseIndent ) {
136+ if ( match === null || ! ( 1 in match ) || match [ 1 ] . length !== baseIndent || ! ( 3 in match ) ) {
117137 break
118138 }
119139
@@ -130,7 +150,7 @@ function parseList(lines: string[], start: number, baseIndent: number): [Token[]
130150 // Now parse subsequent indented lines as sub-items or sub-blocks
131151 while ( i < lines . length ) {
132152 const subline = lines [ i ]
133- if ( subline . trim ( ) === '' ) {
153+ if ( subline === undefined || subline . trim ( ) === '' ) {
134154 i ++
135155 continue
136156 }
@@ -141,9 +161,13 @@ function parseList(lines: string[], start: number, baseIndent: number): [Token[]
141161 // If it’s a fenced code block, parse until closing fence
142162 const language = trimmed . slice ( 3 ) . trim ( ) || undefined
143163 i ++
144- const codeLines = [ ]
145- while ( i < lines . length && ! lines [ i ] . trimStart ( ) . startsWith ( '```' ) ) {
146- codeLines . push ( lines [ i ] )
164+ const codeLines : string [ ] = [ ]
165+ while ( i < lines . length && ! lines [ i ] ?. trimStart ( ) . startsWith ( '```' ) ) {
166+ const line = lines [ i ]
167+ if ( line === undefined ) {
168+ throw new Error ( `Line is undefined at index ${ i } ` )
169+ }
170+ codeLines . push ( line )
147171 i ++
148172 }
149173 i ++ // skip the closing ```
@@ -157,7 +181,7 @@ function parseList(lines: string[], start: number, baseIndent: number): [Token[]
157181
158182 // Check for nested list
159183 const sublistMatch = / ^ ( \s * ) ( [ - * + ] | \d + \. ) \s + ( .* ) / . exec ( subline )
160- if ( sublistMatch && sublistMatch [ 1 ] . length > baseIndent ) {
184+ if ( sublistMatch && 1 in sublistMatch && sublistMatch [ 1 ] . length > baseIndent && 2 in sublistMatch ) {
161185 const newBaseIndent = sublistMatch [ 1 ] . length
162186 const ordered = / ^ \d + \. / . test ( sublistMatch [ 2 ] )
163187 const [ subItems , newIndex ] = parseList ( lines , i , newBaseIndent )
@@ -253,7 +277,11 @@ function parseInlineRecursive(text: string, stop?: string): [Token[], number] {
253277 const [ linkTextTokens , consumed ] = parseInlineRecursive ( text . slice ( i ) , ']' )
254278 i += consumed
255279 if ( i >= text . length || text [ i ] !== ']' ) {
256- tokens . push ( { type : 'text' , content : text [ start ] } )
280+ const startText = text [ start ]
281+ if ( startText === undefined ) {
282+ throw new Error ( `Text is undefined at index ${ start } ` )
283+ }
284+ tokens . push ( { type : 'text' , content : startText } )
257285 continue
258286 }
259287 i ++ // skip ']'
@@ -285,7 +313,11 @@ function parseInlineRecursive(text: string, stop?: string): [Token[], number] {
285313 i ++
286314 let code = ''
287315 while ( i < text . length && text [ i ] !== '`' ) {
288- code += text [ i ]
316+ const character = text [ i ]
317+ if ( character === undefined ) {
318+ throw new Error ( `Character is undefined at index ${ i } ` )
319+ }
320+ code += character
289321 i ++
290322 }
291323 i ++
@@ -311,10 +343,18 @@ function parseInlineRecursive(text: string, stop?: string): [Token[], number] {
311343 if ( delimiter === '*' ) {
312344 let j = i - 1
313345 while ( j >= 0 && text [ j ] === ' ' ) j --
314- const prevIsDigit = j >= 0 && / \d / . test ( text [ j ] )
346+ const characterAtJ = text [ j ]
347+ if ( characterAtJ === undefined ) {
348+ throw new Error ( `Character at index ${ j } is undefined` )
349+ }
350+ const prevIsDigit = j >= 0 && / \d / . test ( characterAtJ )
315351 let k = i + 1
316352 while ( k < text . length && text [ k ] === ' ' ) k ++
317- const nextIsDigit = k < text . length && / \d / . test ( text [ k ] )
353+ const characterAtK = text [ k ]
354+ if ( characterAtK === undefined ) {
355+ throw new Error ( `Character at index ${ j } is undefined` )
356+ }
357+ const nextIsDigit = k < text . length && / \d / . test ( characterAtK )
318358 if ( prevIsDigit && nextIsDigit ) {
319359 tokens . push ( { type : 'text' , content : delimiter } )
320360 i ++
0 commit comments