@@ -7,6 +7,15 @@ type TutorialFrame = {
7
7
levels : T . Level [ ] ;
8
8
} ;
9
9
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
+
10
19
export function parseMdContent ( md : string ) : TutorialFrame | never {
11
20
let start : number = - 1 ;
12
21
const parts : any [ ] = [ ] ;
@@ -34,9 +43,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
34
43
} ;
35
44
36
45
// Capture summary
37
- const summaryMatch = parts
38
- . shift ( )
39
- . match ( / ^ # \s (?< tutorialTitle > .* ) [ \n \r ] + (?< tutorialDescription > [ ^ ] * ) / ) ;
46
+ const summaryMatch = parts . shift ( ) . match ( R . summary ) ;
40
47
if ( summaryMatch . groups . tutorialTitle ) {
41
48
mdContent . summary . title = summaryMatch . groups . tutorialTitle . trim ( ) ;
42
49
}
@@ -49,8 +56,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
49
56
// Identify each part of the content
50
57
parts . forEach ( ( section : string ) => {
51
58
// 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 ) ;
54
60
55
61
if ( levelMatch && levelMatch . groups ) {
56
62
const levelId = levelMatch . groups . levelId . replace ( "." , "" ) ;
@@ -77,8 +83,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
77
83
} ;
78
84
} else {
79
85
// 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 ) ;
82
87
if ( stepMatch && stepMatch . groups ) {
83
88
current = {
84
89
levelId : current . levelId ,
@@ -91,17 +96,14 @@ export function parseMdContent(md: string): TutorialFrame | never {
91
96
content : stepContent . trim ( ) ,
92
97
} ;
93
98
} else {
94
- const hintDetectRegex = / ^ ( # { 4 } \s H I N T S [ \n \r ] + ( [ \* | \- ] \s (?< hintContent > [ ^ ] * ) ) [ \n \r ] + ) + / ;
95
- const hintMatch = section . match ( hintDetectRegex ) ;
96
- const subtaskDetectRegex = / ^ ( # { 4 } \s S U B T A S K S [ \n \r ] + ( [ \* | \- ] \s (?< subtaskContent > [ ^ ] * ) ) [ \n \r ] + ) + / ;
97
- const subtaskMatch = section . match ( subtaskDetectRegex ) ;
98
- const listItemregex = / [ \n \r ] + [ \* | \- ] \s / ;
99
+ const hintMatch = section . match ( R . hints ) ;
100
+ const subtaskMatch = section . match ( R . subtasks ) ;
99
101
100
102
switch ( true ) {
101
103
// parse hints from stepContent
102
104
case ! ! hintMatch :
103
105
const hints = section
104
- . split ( listItemregex )
106
+ . split ( R . listItem )
105
107
. slice ( 1 ) // remove #### HINTS
106
108
. map ( ( h ) => h . trim ( ) ) ;
107
109
if ( hints . length ) {
@@ -113,7 +115,7 @@ export function parseMdContent(md: string): TutorialFrame | never {
113
115
// parse subtasks from stepContent
114
116
case ! ! subtaskMatch :
115
117
const subtasks = section
116
- . split ( listItemregex )
118
+ . split ( R . listItem )
117
119
. slice ( 1 ) // remove #### SUBTASKS
118
120
. map ( ( h ) => h . trim ( ) ) ;
119
121
if ( subtasks . length ) {
0 commit comments