11import ITokenMatcher from './ITokenMatcher'
22import Dialect from './Dialect'
3- import { Token , TokenType } from './Parser'
3+ import { Token , TokenType } from './Parser'
44import DIALECTS from './gherkin-languages.json'
5- import { Item } from './IToken'
5+ import { Item } from './IToken'
66import * as messages from '@cucumber/messages'
7- import { NoSuchLanguageException } from './Errors'
7+ import { NoSuchLanguageException } from './Errors'
8+ import { KeywordPrefixes } from "./flavors/KeywordPrefixes" ;
89
9- const DIALECT_DICT : { [ key : string ] : Dialect } = DIALECTS
10- const DEFAULT_DOC_STRING_SEPARATOR = / ^ ( ` ` ` [ ` ] * ) ( .* ) /
10+
11+ export const DIALECT_DICT : { [ key : string ] : Dialect } = DIALECTS
12+ export const DEFAULT_DOC_STRING_SEPARATOR = / ^ ( ` ` ` [ ` ] * ) ( .* ) /
1113
1214function addKeywordTypeMappings ( h : { [ key : string ] : messages . StepKeywordType [ ] } , keywords : readonly string [ ] , keywordType : messages . StepKeywordType ) {
1315 for ( const k of keywords ) {
@@ -19,17 +21,27 @@ function addKeywordTypeMappings(h: { [key: string]: messages.StepKeywordType[] }
1921}
2022
2123export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher < TokenType > {
22- private dialect : Dialect
23- private dialectName : string
24- private readonly nonStarStepKeywords : string [ ]
24+ dialect : Dialect
25+ dialectName : string
26+ readonly nonStarStepKeywords : string [ ]
2527 private readonly stepRegexp : RegExp
2628 private readonly headerRegexp : RegExp
2729 private activeDocStringSeparator : RegExp
2830 private indentToRemove : number
29- private matchedFeatureLine : boolean
31+ matchedFeatureLine : boolean
32+ private prefixes : KeywordPrefixes = {
33+ // https://spec.commonmark.org/0.29/#bullet-list-marker
34+ BULLET : '^(\\s*[*+-]\\s*)' ,
35+ HEADER : '^(#{1,6}\\s)' ,
36+ }
37+ private readonly docStringSeparator = DEFAULT_DOC_STRING_SEPARATOR ;
38+
3039 private keywordTypesMap : { [ key : string ] : messages . StepKeywordType [ ] }
3140
32- constructor ( private readonly defaultDialectName : string = 'en' ) {
41+ constructor ( private readonly defaultDialectName : string = 'en' , prefixes ?: KeywordPrefixes , docStringSeparator ?: RegExp ) {
42+ prefixes ? this . prefixes = prefixes : null ;
43+ docStringSeparator ? this . docStringSeparator = docStringSeparator : this . docStringSeparator = DEFAULT_DOC_STRING_SEPARATOR ;
44+
3345 this . dialect = DIALECT_DICT [ defaultDialectName ]
3446 this . nonStarStepKeywords = [ ]
3547 . concat ( this . dialect . given )
@@ -41,7 +53,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
4153 this . initializeKeywordTypes ( )
4254
4355 this . stepRegexp = new RegExp (
44- `${ KeywordPrefix . BULLET } (${ this . nonStarStepKeywords . map ( escapeRegExp ) . join ( '|' ) } )`
56+ `${ this . prefixes . BULLET } (${ this . nonStarStepKeywords . map ( escapeRegExp ) . join ( '|' ) } )`
4557 )
4658
4759 const headerKeywords = [ ]
@@ -54,7 +66,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
5466 . filter ( ( value , index , self ) => self . indexOf ( value ) === index )
5567
5668 this . headerRegexp = new RegExp (
57- `${ KeywordPrefix . HEADER } (${ headerKeywords . map ( escapeRegExp ) . join ( '|' ) } )`
69+ `${ this . prefixes . HEADER } (${ headerKeywords . map ( escapeRegExp ) . join ( '|' ) } )`
5870 )
5971
6072 this . reset ( )
@@ -140,11 +152,11 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
140152 const [ , newSeparator , mediaType ] = match || [ ]
141153 let result = false
142154 if ( newSeparator ) {
143- if ( this . activeDocStringSeparator === DEFAULT_DOC_STRING_SEPARATOR ) {
155+ if ( this . activeDocStringSeparator === this . docStringSeparator ) {
144156 this . activeDocStringSeparator = new RegExp ( `^(${ newSeparator } )$` )
145157 this . indentToRemove = token . line . indent
146158 } else {
147- this . activeDocStringSeparator = DEFAULT_DOC_STRING_SEPARATOR
159+ this . activeDocStringSeparator = this . docStringSeparator
148160 }
149161
150162 token . matchedKeyword = newSeparator
@@ -171,7 +183,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
171183 }
172184 // We first try to match "# Feature: blah"
173185 let result = this . matchTitleLine (
174- KeywordPrefix . HEADER ,
186+ this . prefixes . HEADER ,
175187 this . dialect . feature ,
176188 ':' ,
177189 token ,
@@ -191,7 +203,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
191203
192204 match_BackgroundLine ( token : Token ) : boolean {
193205 return this . matchTitleLine (
194- KeywordPrefix . HEADER ,
206+ this . prefixes . HEADER ,
195207 this . dialect . background ,
196208 ':' ,
197209 token ,
@@ -201,7 +213,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
201213
202214 match_RuleLine ( token : Token ) : boolean {
203215 return this . matchTitleLine (
204- KeywordPrefix . HEADER ,
216+ this . prefixes . HEADER ,
205217 this . dialect . rule ,
206218 ':' ,
207219 token ,
@@ -212,14 +224,14 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
212224 match_ScenarioLine ( token : Token ) : boolean {
213225 return (
214226 this . matchTitleLine (
215- KeywordPrefix . HEADER ,
227+ this . prefixes . HEADER ,
216228 this . dialect . scenario ,
217229 ':' ,
218230 token ,
219231 TokenType . ScenarioLine
220232 ) ||
221233 this . matchTitleLine (
222- KeywordPrefix . HEADER ,
234+ this . prefixes . HEADER ,
223235 this . dialect . scenarioOutline ,
224236 ':' ,
225237 token ,
@@ -230,7 +242,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
230242
231243 match_ExamplesLine ( token : Token ) : boolean {
232244 return this . matchTitleLine (
233- KeywordPrefix . HEADER ,
245+ this . prefixes . HEADER ,
234246 this . dialect . examples ,
235247 ':' ,
236248 token ,
@@ -240,7 +252,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
240252
241253 match_StepLine ( token : Token ) : boolean {
242254 return this . matchTitleLine (
243- KeywordPrefix . BULLET ,
255+ this . prefixes . BULLET ,
244256 this . nonStarStepKeywords ,
245257 '' ,
246258 token ,
@@ -249,7 +261,7 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
249261 }
250262
251263 matchTitleLine (
252- prefix : KeywordPrefix ,
264+ prefix : string ,
253265 keywords : readonly string [ ] ,
254266 keywordSuffix : ':' | '' ,
255267 token : Token ,
@@ -333,16 +345,10 @@ export default class GherkinInMarkdownTokenMatcher implements ITokenMatcher<Toke
333345 if ( this . dialectName !== this . defaultDialectName ) {
334346 this . changeDialect ( this . defaultDialectName )
335347 }
336- this . activeDocStringSeparator = DEFAULT_DOC_STRING_SEPARATOR
348+ this . activeDocStringSeparator = this . docStringSeparator ;
337349 }
338350}
339351
340- enum KeywordPrefix {
341- // https://spec.commonmark.org/0.29/#bullet-list-marker
342- BULLET = '^(\\s*[*+-]\\s*)' ,
343- HEADER = '^(#{1,6}\\s)' ,
344- }
345-
346352// https://stackoverflow.com/questions/3115150/how-to-escape-regular-expression-special-characters-using-javascript
347353function escapeRegExp ( text : string ) {
348354 return text . replace ( / [ - [ \] { } ( ) * + ? . , \\ ^ $ | # \s ] / g, '\\$&' )
0 commit comments