@@ -7,6 +7,15 @@ type TutorialFrame = {
77 levels : T . Level [ ] ;
88} ;
99
10+ const R = {
11+ summary : / ^ # \s (?< tutorialTitle > .* ) [ \n \r ] + (?< tutorialDescription > [ ^ ] * ) / ,
12+ level : / ^ ( # { 2 } \s (?< levelId > L ? \d + \. ? ) \s (?< levelTitle > .* ) [ \n \r ] * ( > \s (?< levelSummary > .* ) ) ? [ \n \r ] + (?< levelContent > [ ^ ] * ) ) / ,
13+ step : / ^ ( # { 3 } \s (?< stepTitle > .* ) [ \n \r ] + (?< stepContent > [ ^ ] * ) ) / ,
14+ hints : / ^ ( # { 4 } \s H I N T S [ \n \r ] + ( [ \* | \- ] \s (?< hintContent > [ ^ ] * ) ) [ \n \r ] + ) + / ,
15+ subtasks : / ^ ( # { 4 } \s S U B T A S K S [ \n \r ] + ( [ \* | \- ] \s (?< subtaskContent > [ ^ ] * ) ) [ \n \r ] + ) + / ,
16+ listItem : / [ \n \r ] + [ \* | \- ] \s / ,
17+ } ;
18+
1019export function parseMdContent ( md : string ) : TutorialFrame | never {
1120 let start : number = - 1 ;
1221 const parts : any [ ] = [ ] ;
@@ -34,9 +43,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
3443 } ;
3544
3645 // Capture summary
37- const summaryMatch = parts
38- . shift ( )
39- . match ( / ^ # \s (?< tutorialTitle > .* ) [ \n \r ] + (?< tutorialDescription > [ ^ ] * ) / ) ;
46+ const summaryMatch = parts . shift ( ) . match ( R . summary ) ;
4047 if ( summaryMatch . groups . tutorialTitle ) {
4148 mdContent . summary . title = summaryMatch . groups . tutorialTitle . trim ( ) ;
4249 }
@@ -49,8 +56,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
4956 // Identify each part of the content
5057 parts . forEach ( ( section : string ) => {
5158 // match level
52- const levelRegex = / ^ ( # { 2 } \s (?< levelId > L ? \d + \. ? ) \s (?< levelTitle > .* ) [ \n \r ] * ( > \s (?< levelSummary > .* ) ) ? [ \n \r ] + (?< levelContent > [ ^ ] * ) ) / ;
53- const levelMatch : RegExpMatchArray | null = section . match ( levelRegex ) ;
59+ const levelMatch : RegExpMatchArray | null = section . match ( R . level ) ;
5460
5561 if ( levelMatch && levelMatch . groups ) {
5662 const levelId = levelMatch . groups . levelId . replace ( "." , "" ) ;
@@ -77,8 +83,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
7783 } ;
7884 } else {
7985 // match step
80- const stepRegex = / ^ ( # { 3 } \s (?< stepTitle > .* ) [ \n \r ] + (?< stepContent > [ ^ ] * ) ) / ;
81- const stepMatch : RegExpMatchArray | null = section . match ( stepRegex ) ;
86+ const stepMatch : RegExpMatchArray | null = section . match ( R . step ) ;
8287 if ( stepMatch && stepMatch . groups ) {
8388 current = {
8489 levelId : current . levelId ,
@@ -91,20 +96,36 @@ export function parseMdContent(md: string): TutorialFrame | never {
9196 content : stepContent . trim ( ) ,
9297 } ;
9398 } else {
94- // parse hints from stepContent
95- const hintDetectRegex = / ^ ( # { 4 } \s H I N T S [ \n \r ] + ( [ \* | \- ] \s (?< hintContent > [ ^ ] * ) ) [ \n \r ] + ) + / ;
96- const hintMatch = section . match ( hintDetectRegex ) ;
97- if ( ! ! hintMatch ) {
98- const hintItemRegex = / [ \n \r ] + [ \* | \- ] \s / ;
99- const hints = section
100- . split ( hintItemRegex )
101- . slice ( 1 ) // remove #### HINTS
102- . map ( ( h ) => h . trim ( ) ) ;
103- if ( hints . length ) {
104- mdContent . levels [ current . levelIndex ] . steps [
105- current . stepIndex
106- ] . hints = hints ;
107- }
99+ const hintMatch = section . match ( R . hints ) ;
100+ const subtaskMatch = section . match ( R . subtasks ) ;
101+
102+ switch ( true ) {
103+ // parse hints from stepContent
104+ case ! ! hintMatch :
105+ const hints = section
106+ . split ( R . listItem )
107+ . slice ( 1 ) // remove #### HINTS
108+ . map ( ( h ) => h . trim ( ) ) ;
109+ if ( hints . length ) {
110+ mdContent . levels [ current . levelIndex ] . steps [
111+ current . stepIndex
112+ ] . hints = hints ;
113+ }
114+ return ;
115+ // parse subtasks from stepContent
116+ case ! ! subtaskMatch :
117+ const subtasks = section
118+ . split ( R . listItem )
119+ . slice ( 1 ) // remove #### SUBTASKS
120+ . map ( ( h ) => h . trim ( ) ) ;
121+ if ( subtasks . length ) {
122+ mdContent . levels [ current . levelIndex ] . steps [
123+ current . stepIndex
124+ ] . subtasks = subtasks ;
125+ }
126+ return ;
127+ default :
128+ console . warn ( `No build parser match found for:\n${ section } \n` ) ;
108129 }
109130 }
110131 }
0 commit comments