@@ -31,13 +31,13 @@ const crlfRegex = /\r\n/gm;
31
31
const propertyRegex = / ^ \s + ( [ a - z A - Z ] + ) : \s * ( .+ ) / ;
32
32
const headerEndCodeStartRegex = / ^ \s * - - - \s * ` ` ` .* \n / ;
33
33
const codeRegex = / ^ ( .+ ) ` ` ` / s
34
- function parseSnippet ( snippetPath , name , text ) {
35
- if ( crlfRegex . exec ( text ) !== null ) return raise ( 'Found CRLF line endings instead of LF line endings' , snippetPath ) ;
34
+ function parseSnippet ( path , name , text ) {
35
+ if ( crlfRegex . exec ( text ) !== null ) return raise ( 'Found CRLF line endings instead of LF line endings' , path ) ;
36
36
let cursor = 0 ;
37
37
38
38
const fromCursor = ( ) => text . substring ( cursor ) ;
39
39
40
- if ( ! fromCursor ( ) . trim ( ) . startsWith ( '---' ) ) return raise ( 'Missing header start delimiter \'---\'' , snippetPath ) ;
40
+ if ( ! fromCursor ( ) . trim ( ) . startsWith ( '---' ) ) return raise ( 'Missing header start delimiter \'---\'' , path ) ;
41
41
cursor += 3 ;
42
42
43
43
const properties = { } ;
@@ -47,19 +47,19 @@ function parseSnippet(snippetPath, name, text) {
47
47
properties [ match [ 1 ] . toLowerCase ( ) ] = match [ 2 ] ;
48
48
}
49
49
50
- if ( ! ( 'title' in properties ) ) return raise ( `Missing 'title' property` , snippetPath ) ;
51
- if ( ! ( 'description' in properties ) ) return raise ( `Missing 'description' property` , snippetPath ) ;
52
- if ( ! ( 'author' in properties ) ) return raise ( `Missing 'author' property` , snippetPath ) ;
53
- if ( ! ( 'tags' in properties ) ) return raise ( `Missing 'tags' property` , snippetPath ) ;
50
+ if ( ! ( 'title' in properties ) ) return raise ( `Missing 'title' property` , path ) ;
51
+ if ( ! ( 'description' in properties ) ) return raise ( `Missing 'description' property` , path ) ;
52
+ if ( ! ( 'author' in properties ) ) return raise ( `Missing 'author' property` , path ) ;
53
+ if ( ! ( 'tags' in properties ) ) return raise ( `Missing 'tags' property` , path ) ;
54
54
55
- if ( slugify ( properties . title ) !== name ) return raise ( `slugifyed 'title' property doesn't match snippet file name` , snippetPath ) ;
55
+ if ( slugify ( properties . title ) !== name ) return raise ( `slugifyed 'title' property doesn't match snippet file name` , path ) ;
56
56
57
57
match = headerEndCodeStartRegex . exec ( fromCursor ( ) ) ;
58
- if ( match === null ) return raise ( 'Missing header end \'---\' or code start \'```\'' , snippetPath ) ;
58
+ if ( match === null ) return raise ( 'Missing header end \'---\' or code start \'```\'' , path ) ;
59
59
cursor += match [ 0 ] . length ;
60
60
61
61
match = codeRegex . exec ( fromCursor ( ) ) ;
62
- if ( match === null ) return raise ( 'Missing code block end \'```\'' , snippetPath ) ;
62
+ if ( match === null ) return raise ( 'Missing code block end \'```\'' , path ) ;
63
63
const code = match [ 1 ] ;
64
64
65
65
return {
@@ -72,43 +72,63 @@ function parseSnippet(snippetPath, name, text) {
72
72
}
73
73
}
74
74
75
+ function parseCategory ( path , name ) {
76
+ const snippets = [ ] ;
77
+
78
+ for ( const snippet of readdirSync ( path ) ) {
79
+ const snippetPath = join ( path , snippet ) ;
80
+ const snippetContent = readFileSync ( snippetPath ) . toString ( ) ;
81
+ const snippetFileName = snippet . slice ( 0 , - 3 ) ;
82
+
83
+ const snippetData = parseSnippet ( snippetPath , snippetFileName , snippetContent ) ;
84
+ if ( ! snippetData ) continue ;
85
+ snippets . push ( snippetData ) ;
86
+ }
87
+
88
+ return {
89
+ name : reverseSlugify ( name ) ,
90
+ snippets,
91
+ } ;
92
+ }
93
+
94
+ function parseLanguage ( path , name , subLanguageOf = null ) {
95
+ const iconPath = join ( path , 'icon.svg' ) ;
96
+
97
+ if ( ! existsSync ( iconPath ) ) return raise ( `icon for '${ subLanguageOf ? `${ subLanguageOf } /` : '' } ${ name } ' is missing` ) ;
98
+
99
+ const categories = [ ] ;
100
+ const subLanguages = [ ] ;
101
+
102
+ for ( const category of readdirSync ( path ) ) {
103
+ if ( category === 'icon.svg' ) continue ;
104
+ const categoryPath = join ( path , category ) ;
105
+
106
+ if ( category . startsWith ( '[' ) && category . endsWith ( ']' ) ) {
107
+ if ( subLanguageOf !== null ) {
108
+ return raise ( 'Cannot have more than two level of language nesting' ) ;
109
+ }
110
+ subLanguages . push ( parseLanguage ( categoryPath , category . slice ( 1 , - 1 ) , name ) ) ;
111
+ } else {
112
+ categories . push ( parseCategory ( categoryPath , category ) ) ;
113
+ }
114
+ }
115
+
116
+ return {
117
+ name : reverseSlugify ( name ) ,
118
+ icon : iconPath ,
119
+ categories, subLanguages,
120
+ }
121
+ }
122
+
75
123
const snippetPath = "snippets/" ;
76
124
export function parseAllSnippets ( ) {
77
- const snippets = { } ;
125
+ const languages = [ ] ;
78
126
79
127
for ( const language of readdirSync ( snippetPath ) ) {
80
128
const languagePath = join ( snippetPath , language ) ;
81
-
82
- const languageIconPath = join ( languagePath , 'icon.svg' ) ;
83
-
84
- if ( ! existsSync ( languageIconPath ) ) {
85
- raise ( `icon for '${ language } ' is missing` ) ;
86
- continue ;
87
- }
88
-
89
- const categories = [ ] ;
90
- for ( const category of readdirSync ( languagePath ) ) {
91
- if ( category === 'icon.svg' ) continue ;
92
- const categoryPath = join ( languagePath , category ) ;
93
-
94
- const categorySnippets = [ ] ;
95
- for ( const snippet of readdirSync ( categoryPath ) ) {
96
- const snippetPath = join ( categoryPath , snippet ) ;
97
- const snippetContent = readFileSync ( snippetPath ) . toString ( ) ;
98
- const snippetFileName = snippet . slice ( 0 , - 3 ) ;
99
-
100
- const snippetData = parseSnippet ( snippetPath , snippetFileName , snippetContent ) ;
101
- if ( ! snippetData ) continue ;
102
- categorySnippets . push ( snippetData ) ;
103
- }
104
- categories . push ( {
105
- categoryName : reverseSlugify ( category ) ,
106
- snippets : categorySnippets ,
107
- } ) ;
108
- }
109
129
110
- snippets [ language ] = categories ;
130
+ languages . push ( parseLanguage ( languagePath , language ) ) ;
111
131
}
112
132
113
- return [ errored , snippets ] ;
133
+ return [ errored , languages ] ;
114
134
}
0 commit comments