@@ -50,6 +50,93 @@ function _annotateTokenLines(tokens) {
5050 if ( token . type !== "space" ) {
5151 token . _sourceLine = line ;
5252 }
53+ // Recursively annotate children with their source lines
54+ _annotateTokenChildren ( token , line ) ;
55+ if ( token . raw ) {
56+ line += ( token . raw . match ( / \n / g) || [ ] ) . length ;
57+ }
58+ }
59+ }
60+
61+ function _annotateTokenChildren ( token , startLine ) {
62+ // List items
63+ if ( token . type === "list" && token . items ) {
64+ let itemLine = startLine ;
65+ for ( const item of token . items ) {
66+ item . _sourceLine = itemLine ;
67+ if ( item . tokens ) {
68+ _annotateNestedTokens ( item . tokens , itemLine ) ;
69+ }
70+ if ( item . raw ) {
71+ itemLine += ( item . raw . match ( / \n / g) || [ ] ) . length ;
72+ }
73+ }
74+ }
75+ // Blockquote children
76+ if ( token . type === "blockquote" && token . tokens ) {
77+ _annotateNestedTokens ( token . tokens , startLine ) ;
78+ }
79+ // Table rows
80+ if ( token . type === "table" ) {
81+ if ( token . header ) {
82+ for ( const cell of token . header ) {
83+ cell . _sourceLine = startLine ;
84+ }
85+ }
86+ if ( token . rows ) {
87+ let rowLine = startLine + 2 ;
88+ for ( const row of token . rows ) {
89+ for ( const cell of row ) {
90+ cell . _sourceLine = rowLine ;
91+ }
92+ rowLine ++ ;
93+ }
94+ }
95+ }
96+ }
97+
98+ function _annotateNestedTokens ( tokens , startLine ) {
99+ let line = startLine ;
100+ for ( const token of tokens ) {
101+ if ( token . type !== "space" ) {
102+ token . _sourceLine = line ;
103+ }
104+ // Recurse into nested lists
105+ if ( token . type === "list" && token . items ) {
106+ let itemLine = line ;
107+ for ( const item of token . items ) {
108+ item . _sourceLine = itemLine ;
109+ if ( item . tokens ) {
110+ _annotateNestedTokens ( item . tokens , itemLine ) ;
111+ }
112+ if ( item . raw ) {
113+ itemLine += ( item . raw . match ( / \n / g) || [ ] ) . length ;
114+ }
115+ }
116+ }
117+ // Recurse into blockquote children
118+ if ( token . type === "blockquote" && token . tokens ) {
119+ _annotateNestedTokens ( token . tokens , line ) ;
120+ }
121+ // Annotate table rows
122+ if ( token . type === "table" ) {
123+ // Header row
124+ if ( token . header ) {
125+ for ( const cell of token . header ) {
126+ cell . _sourceLine = line ;
127+ }
128+ }
129+ // Body rows: each row is one line after header + separator (2 lines)
130+ if ( token . rows ) {
131+ let rowLine = line + 2 ; // skip header + separator lines
132+ for ( const row of token . rows ) {
133+ for ( const cell of row ) {
134+ cell . _sourceLine = rowLine ;
135+ }
136+ rowLine ++ ;
137+ }
138+ }
139+ }
53140 if ( token . raw ) {
54141 line += ( token . raw . match ( / \n / g) || [ ] ) . length ;
55142 }
@@ -74,7 +161,9 @@ marked.use({
74161 heading : _withSourceLine ( _proto . heading , / ^ < h [ 1 - 6 ] / ) ,
75162 paragraph : _withSourceLine ( _proto . paragraph , / ^ < p / ) ,
76163 list : _withSourceLine ( _proto . list , / ^ < [ o u ] l / ) ,
164+ listitem : _withSourceLine ( _proto . listitem , / ^ < l i / ) ,
77165 table : _withSourceLine ( _proto . table , / ^ < t a b l e / ) ,
166+ tablecell : _withSourceLine ( _proto . tablecell , / ^ < t [ d h ] / ) ,
78167 blockquote : _withSourceLine ( _proto . blockquote , / ^ < b l o c k q u o t e / ) ,
79168 code : _withSourceLine ( _proto . code , / ^ < p r e / ) ,
80169 hr : _withSourceLine ( _proto . hr , / ^ < h r / )
0 commit comments