@@ -4,146 +4,147 @@ import showdown from 'showdown'
44import fm from 'front-matter'
55import prism from 'prismjs'
66import loadLanguages from 'prismjs/components/index.js'
7+
78loadLanguages ( [ 'scss' , 'css-extras' ] )
89
910const DIRECTORIES = {
10- sass : {
11- input : './sass/themes/' ,
12- output : './site/_data/sass/'
13- } ,
14- api : {
15- input : './sass/utils/' ,
16- output : './site/_data/sass/'
17- }
11+ sass : {
12+ input : './sass/themes/' ,
13+ output : './site/_data/sass/'
14+ } ,
15+ api : {
16+ input : './sass/utils/' ,
17+ output : './site/_data/sass/'
18+ }
1819}
1920
2021const processSassDocumentation = file => {
21- const inputFileExtension = path . extname ( file )
22- const inputFilename = path . basename ( file , inputFileExtension )
23- const excludeFiles = [ '_all' ]
24-
25- // Exclude files that we don't want to process
26- if ( inputFileExtension !== '.scss' || excludeFiles . includes ( inputFilename ) ) {
27- return
28- }
29-
30- const content = fs . readFileSync ( file , 'utf8' )
31- const commentBlockRegex = / \/ \* d o c ( .) * ?\* \/ / gs
32-
33- const comments = Array . from ( content . matchAll ( commentBlockRegex ) , data => {
34- return parseSassComment ( data [ 0 ] )
35- } )
36-
37- // Avoid crash if output directory does not exists
38- if ( ! fs . existsSync ( DIRECTORIES . sass . output ) ) {
39- fs . mkdirSync ( DIRECTORIES . sass . output )
40- }
41-
42- // Write Eleventy data files
43- fs . writeFileSync (
44- `${ DIRECTORIES . sass . output } /${ inputFilename . replace ( '_' , '' ) } .json` ,
45- JSON . stringify ( comments , null , 2 )
46- )
22+ const inputFileExtension = path . extname ( file )
23+ const inputFilename = path . basename ( file , inputFileExtension )
24+ const excludeFiles = [ '_all' ]
25+
26+ // Exclude files that we don't want to process
27+ if ( inputFileExtension !== '.scss' || excludeFiles . includes ( inputFilename ) ) {
28+ return
29+ }
30+
31+ const content = fs . readFileSync ( file , 'utf8' )
32+ const commentBlockRegex = / \/ \* d o c ( .) * ?\* \/ / gs
33+
34+ const comments = Array . from ( content . matchAll ( commentBlockRegex ) , data => {
35+ return parseSassComment ( data [ 0 ] )
36+ } )
37+
38+ // Avoid crash if output directory does not exists
39+ if ( ! fs . existsSync ( DIRECTORIES . sass . output ) ) {
40+ fs . mkdirSync ( DIRECTORIES . sass . output )
41+ }
42+
43+ // Write Eleventy data files
44+ fs . writeFileSync (
45+ `${ DIRECTORIES . sass . output } /${ inputFilename . replace ( '_' , '' ) } .json` ,
46+ JSON . stringify ( comments , null , 2 )
47+ )
4748}
4849
4950const processApiDocumentation = file => {
50- const content = fs . readFileSync ( file , 'utf8' )
51- const commentBlockRegex = / \/ \* d o c ( .) * ?\* \/ / gs
51+ const content = fs . readFileSync ( file , 'utf8' )
52+ const commentBlockRegex = / \/ \* d o c ( .) * ?\* \/ / gs
5253
53- const comments = Array . from ( content . matchAll ( commentBlockRegex ) , data => {
54- return parseSassComment ( data [ 0 ] )
55- } )
54+ const comments = Array . from ( content . matchAll ( commentBlockRegex ) , data => {
55+ return parseSassComment ( data [ 0 ] )
56+ } )
5657
57- // Avoid crash if output directory does not exists
58- if ( ! fs . existsSync ( DIRECTORIES . api . output ) ) {
59- fs . mkdirSync ( DIRECTORIES . api . output )
60- }
58+ // Avoid crash if output directory does not exists
59+ if ( ! fs . existsSync ( DIRECTORIES . api . output ) ) {
60+ fs . mkdirSync ( DIRECTORIES . api . output )
61+ }
6162
62- return comments
63+ return comments
6364}
6465
6566const parseSassComment = comment => {
66- // Remove CSS comments syntax
67- comment = comment . replace ( / ( \/ \* d o c | \* \/ ) / g, '' ) . trim ( )
68-
69- const content = fm ( comment )
70- let processedContent = new showdown . Converter ( {
71- tables : true ,
72- customizedHeaderId : true ,
73- ghCompatibleHeaderId : true
74- } ) . makeHtml ( content . body )
75-
76- const headingsRegex = / ( < h ( [ 2 - 5 ] ) .* > ( .* ) < \/ h [ 2 - 5 ] > ) / gim
77- processedContent = processedContent . replace ( headingsRegex , `<h$2>$3</h$2>` )
78-
79- // HTML code blocks
80- const markupRegex = / ( ( < p r e > < c o d e c l a s s = " h t m l l a n g u a g e - h t m l " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
81- const htmlRegex = / ( (?< = < c o d e c l a s s = " h t m l l a n g u a g e - h t m l " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
82- let htmlContent = processedContent . match ( htmlRegex )
83- htmlContent = String ( htmlContent ) . replace ( / ( & l t ; ) + / g, '<' )
84- htmlContent = htmlContent . replace ( / ( & g t ; ) + / g, '>' )
85- let processedHTML = prism . highlight ( htmlContent , prism . languages . html , 'html' )
86- processedContent = processedContent . replace ( markupRegex , `<div class="pre"><div>${ htmlContent } </div><pre><code class="html language-html" data-language="Example">${ processedHTML } </code></pre></div>` )
87-
88- // CSS code blocks
89- const stylesRegex = / ( ( < p r e > < c o d e c l a s s = " c s s l a n g u a g e - c s s " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
90- const cssRegex = / ( (?< = < c o d e c l a s s = " c s s l a n g u a g e - c s s " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
91- let cssContent = processedContent . match ( cssRegex )
92- cssContent = String ( cssContent ) . replace ( / ( & g t ; ) + / g, '>' )
93- let processedCSS = prism . highlight ( String ( cssContent ) , prism . languages . css , 'css-extras' )
94- processedContent = processedContent . replace ( stylesRegex , `<div class="pre"><pre><code class="css language-css" data-language="CSS">${ processedCSS } </code></pre></div>` )
95-
96- // SCSS code blocks
97- const scssBlockRegex = / ( ( < p r e > < c o d e c l a s s = " s c s s l a n g u a g e - s c s s " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
98- const scssRegex = / ( (?< = < c o d e c l a s s = " s c s s l a n g u a g e - s c s s " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
99- let scssContent = processedContent . match ( scssRegex )
100- scssContent = String ( scssContent ) . replace ( / ( & a m p ; ) + / g, '&' )
101- scssContent = String ( scssContent ) . replace ( / ( & g t ; ) + / g, '>' )
102- let processedSCSS = prism . highlight ( String ( scssContent ) , prism . languages . scss , 'scss' )
103- processedContent = processedContent . replace ( scssBlockRegex , `<div class="pre"><pre><code class="scss language-scss" data-language="Sass">${ processedSCSS } </code></pre></div>` )
104-
105- // Sass code blocks
106- const sassBlockRegex = / ( ( < p r e > < c o d e c l a s s = " s a s s l a n g u a g e - s a s s " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
107- const sassRegex = / ( (?< = < c o d e c l a s s = " s a s s l a n g u a g e - s a s s " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
108- const sassContent = processedContent . match ( sassRegex )
109- let processedSASS = prism . highlight ( String ( sassContent ) , prism . languages . scss , 'scss' )
110- processedContent = processedContent . replace ( sassBlockRegex , `<div class="pre"><pre><code class="scss language-scss" data-language="Sass">${ processedSASS } </code></pre></div>` )
111-
112- return {
113- attributes : content . attributes ,
114- body : processedContent
115- }
67+ // Remove CSS comments syntax
68+ comment = comment . replace ( / ( \/ \* d o c | \* \/ ) / g, '' ) . trim ( )
69+
70+ const content = fm ( comment )
71+ let processedContent = new showdown . Converter ( {
72+ tables : true ,
73+ customizedHeaderId : true ,
74+ ghCompatibleHeaderId : true
75+ } ) . makeHtml ( content . body )
76+
77+ const headingsRegex = / ( < h ( [ 2 - 5 ] ) .* > ( .* ) < \/ h [ 2 - 5 ] > ) / gim
78+ processedContent = processedContent . replace ( headingsRegex , `<h$2>$3</h$2>` )
79+
80+ // HTML code blocks
81+ const markupRegex = / ( ( < p r e > < c o d e c l a s s = " h t m l l a n g u a g e - h t m l " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
82+ const htmlRegex = / ( (?< = < c o d e c l a s s = " h t m l l a n g u a g e - h t m l " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
83+ let htmlContent = processedContent . match ( htmlRegex )
84+ htmlContent = String ( htmlContent ) . replace ( / ( & l t ; ) + / g, '<' )
85+ htmlContent = htmlContent . replace ( / ( & g t ; ) + / g, '>' )
86+ let processedHTML = prism . highlight ( htmlContent , prism . languages . html , 'html' )
87+ processedContent = processedContent . replace ( markupRegex , `<div class="pre"><div>${ htmlContent } </div><pre><code class="html language-html" data-language="Example">${ processedHTML } </code></pre></div>` )
88+
89+ // CSS code blocks
90+ const stylesRegex = / ( ( < p r e > < c o d e c l a s s = " c s s l a n g u a g e - c s s " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
91+ const cssRegex = / ( (?< = < c o d e c l a s s = " c s s l a n g u a g e - c s s " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
92+ let cssContent = processedContent . match ( cssRegex )
93+ cssContent = String ( cssContent ) . replace ( / ( & g t ; ) + / g, '>' )
94+ let processedCSS = prism . highlight ( String ( cssContent ) , prism . languages . css , 'css-extras' )
95+ processedContent = processedContent . replace ( stylesRegex , `<div class="pre"><pre><code class="css language-css" data-language="CSS">${ processedCSS } </code></pre></div>` )
96+
97+ // SCSS code blocks
98+ const scssBlockRegex = / ( ( < p r e > < c o d e c l a s s = " s c s s l a n g u a g e - s c s s " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
99+ const scssRegex = / ( (?< = < c o d e c l a s s = " s c s s l a n g u a g e - s c s s " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
100+ let scssContent = processedContent . match ( scssRegex )
101+ scssContent = String ( scssContent ) . replace ( / ( & a m p ; ) + / g, '&' )
102+ scssContent = String ( scssContent ) . replace ( / ( & g t ; ) + / g, '>' )
103+ let processedSCSS = prism . highlight ( String ( scssContent ) , prism . languages . scss , 'scss' )
104+ processedContent = processedContent . replace ( scssBlockRegex , `<div class="pre"><pre><code class="scss language-scss" data-language="Sass">${ processedSCSS } </code></pre></div>` )
105+
106+ // Sass code blocks
107+ const sassBlockRegex = / ( ( < p r e > < c o d e c l a s s = " s a s s l a n g u a g e - s a s s " > ) ( .[ \s \S ] + ?) ( \/ c o d e > < \/ p r e > ) ) / gm
108+ const sassRegex = / ( (?< = < c o d e c l a s s = " s a s s l a n g u a g e - s a s s " > ) ( .[ \s \S ] + ?) (? = < \/ c o d e > ) ) / gm
109+ const sassContent = processedContent . match ( sassRegex )
110+ let processedSASS = prism . highlight ( String ( sassContent ) , prism . languages . scss , 'scss' )
111+ processedContent = processedContent . replace ( sassBlockRegex , `<div class="pre"><pre><code class="scss language-scss" data-language="Sass">${ processedSASS } </code></pre></div>` )
112+
113+ return {
114+ attributes : content . attributes ,
115+ body : processedContent
116+ }
116117}
117118
118119const generateJsonDocumentation = ( ) => {
119- /**
120- * Remove output directory before creating it again
121- * @note This is an experimental feature and requires Node v12.10.0 at least
122- * @see https://nodejs.org/api/fs.html#fs_fs_rmdirsync_path_options
123- */
124- fs . rmSync ( DIRECTORIES . sass . output , { recursive : true , force : true } )
125- fs . rmSync ( DIRECTORIES . api . output , { recursive : true , force : true } )
126-
127- fs . readdirSync ( DIRECTORIES . sass . input ) . forEach ( file => {
128- processSassDocumentation ( DIRECTORIES . sass . input + file )
129- } )
130-
131- let contentAPI = [ ]
132- fs . readdirSync ( DIRECTORIES . api . input ) . forEach ( ( file ) => {
133- if ( [ '_all' ] . includes ( path . basename ( file , '.scss' ) ) ) {
134- return
135- }
136-
137- contentAPI = contentAPI . concat ( processApiDocumentation ( DIRECTORIES . api . input + file ) )
138- } )
139-
140- // Write Eleventy data files
141- fs . writeFileSync (
142- `${ DIRECTORIES . api . output } /api.json` ,
143- JSON . stringify ( contentAPI , null , 2 )
144- )
120+ /**
121+ * Remove output directory before creating it again
122+ * @note This is an experimental feature and requires Node v12.10.0 at least
123+ * @see https://nodejs.org/api/fs.html#fs_fs_rmdirsync_path_options
124+ */
125+ fs . rmSync ( DIRECTORIES . sass . output , { recursive : true , force : true } )
126+ fs . rmSync ( DIRECTORIES . api . output , { recursive : true , force : true } )
127+
128+ fs . readdirSync ( DIRECTORIES . sass . input ) . forEach ( file => {
129+ processSassDocumentation ( DIRECTORIES . sass . input + file )
130+ } )
131+
132+ let contentAPI = [ ]
133+ fs . readdirSync ( DIRECTORIES . api . input ) . forEach ( ( file ) => {
134+ if ( [ '_all' ] . includes ( path . basename ( file , '.scss' ) ) ) {
135+ return
136+ }
137+
138+ contentAPI = contentAPI . concat ( processApiDocumentation ( DIRECTORIES . api . input + file ) )
139+ } )
140+
141+ // Write Eleventy data files
142+ fs . writeFileSync (
143+ `${ DIRECTORIES . api . output } /api.json` ,
144+ JSON . stringify ( contentAPI , null , 2 )
145+ )
145146}
146147
147148export default function ( ) {
148- generateJsonDocumentation ( )
149+ generateJsonDocumentation ( )
149150}
0 commit comments