11import { Token } from '../classes/token.js' ;
22import singleton from '../prism.js' ;
33import { tokenize } from './tokenize.js' ;
4- import { resolve } from './util.js' ;
4+ import { resolve , tokenizeByNamedGroups } from './util.js' ;
55
66/**
77 * @this {Prism}
@@ -21,7 +21,12 @@ export function _matchGrammar (text, tokenList, grammar, startNode, startPos, re
2121
2222 for ( const token in grammar ) {
2323 const tokenValue = grammar [ token ] ;
24- if ( ! grammar . hasOwnProperty ( token ) || token . startsWith ( '$' ) || ! tokenValue ) {
24+ if (
25+ ! grammar . hasOwnProperty ( token ) ||
26+ token . startsWith ( '$' ) ||
27+ ! tokenValue ||
28+ typeof tokenValue === 'function' // functional tokens ($inside for now) are handled on L170, and we should ignore them in all other cases
29+ ) {
2530 continue ;
2631 }
2732
@@ -36,9 +41,20 @@ export function _matchGrammar (text, tokenList, grammar, startNode, startPos, re
3641 let { pattern, lookbehind = false , greedy = false , alias, inside } = patternObj ;
3742 const insideGrammar = resolve . call ( prism , inside ) ;
3843
44+ let flagsToAdd = '' ;
45+
3946 if ( greedy && ! pattern . global ) {
4047 // Without the global flag, lastIndex won't work
41- patternObj . pattern = pattern = RegExp ( pattern . source , pattern . flags + 'g' ) ;
48+ flagsToAdd += 'g' ;
49+ }
50+
51+ if ( pattern . source ?. includes ( '(?<' ) && pattern . hasIndices === false ) {
52+ // Has named groups, we need to be able to capture their indices
53+ flagsToAdd += 'd' ;
54+ }
55+
56+ if ( flagsToAdd ) {
57+ patternObj . pattern = pattern = RegExp ( pattern . source , pattern . flags + flagsToAdd ) ;
4258 }
4359
4460 for (
@@ -63,7 +79,8 @@ export function _matchGrammar (text, tokenList, grammar, startNode, startPos, re
6379 }
6480
6581 let removeCount = 1 ; // this is the to parameter of removeBetween
66- let match ;
82+ /** @type {RegExpExecArray | null } */
83+ let match = null ;
6784
6885 if ( greedy ) {
6986 match = matchPattern ( pattern , pos , text , lookbehind ) ;
@@ -117,6 +134,10 @@ export function _matchGrammar (text, tokenList, grammar, startNode, startPos, re
117134
118135 const from = match . index ;
119136 const matchStr = match [ 0 ] ;
137+
138+ /** @type {TokenStream | string } */
139+ let content = matchStr ;
140+
120141 const before = str . slice ( 0 , from ) ;
121142 const after = str . slice ( from + matchStr . length ) ;
122143
@@ -134,14 +155,42 @@ export function _matchGrammar (text, tokenList, grammar, startNode, startPos, re
134155
135156 tokenList . removeRange ( removeFrom , removeCount ) ;
136157
137- const wrapped = new Token (
138- token ,
139- insideGrammar
140- ? tokenize . call ( prism , matchStr , /** @type {Grammar } */ ( insideGrammar ) )
141- : matchStr ,
142- alias ,
143- matchStr
144- ) ;
158+ const byGroups = match . groups ? tokenizeByNamedGroups ( match ) : null ;
159+ if ( byGroups && byGroups . length > 1 ) {
160+ content = byGroups
161+ . map ( arg => {
162+ let content = typeof arg === 'string' ? arg : arg . content ;
163+ const type = typeof arg === 'string' ? undefined : arg . type ;
164+
165+ if ( insideGrammar ) {
166+ let localInsideGrammar = type ? insideGrammar [ type ] : insideGrammar ;
167+
168+ if ( typeof localInsideGrammar === 'function' ) {
169+ // Late resolving
170+ localInsideGrammar = resolve . call (
171+ prism ,
172+ localInsideGrammar ( match . groups )
173+ ) ;
174+ }
175+
176+ if ( localInsideGrammar ) {
177+ // @ts -ignore
178+ content = tokenize . call ( prism , content , localInsideGrammar ) ;
179+ }
180+ }
181+
182+ return typeof arg === 'object' && arg . type
183+ ? new Token ( arg . type , content )
184+ : content ;
185+ } )
186+ . flat ( ) ; // Flatten tokens like ['foo']
187+ }
188+ else if ( insideGrammar ) {
189+ // @ts -ignore
190+ content = tokenize . call ( prism , content , insideGrammar ) ;
191+ }
192+
193+ const wrapped = new Token ( token , content , alias , matchStr ) ;
145194 currentNode = tokenList . addAfter ( removeFrom , wrapped ) ;
146195
147196 if ( after ) {
@@ -216,7 +265,7 @@ function toGrammarToken (pattern) {
216265
217266/**
218267 * @import { Prism } from '../prism.js';
219- * @import { Grammar, GrammarToken, GrammarTokens, RegExpLike } from '../../types.d.ts';
268+ * @import { Grammar, GrammarToken, GrammarTokens, TokenStream, RegExpLike } from '../../types.d.ts';
220269 */
221270
222271/**
0 commit comments