| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  | const { readSync } = require('to-vfile'); | 
					
						
							|  |  |  | const remark = require('remark-parse'); | 
					
						
							|  |  |  | const directive = require('remark-directive'); | 
					
						
							|  |  |  | const frontmatter = require('remark-frontmatter'); | 
					
						
							|  |  |  | const addTests = require('./plugins/add-tests'); | 
					
						
							| 
									
										
										
										
											2021-02-22 04:44:12 +01:00
										 |  |  | const restoreDirectives = require('./plugins/restore-directives'); | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  | const replaceImports = require('./plugins/replace-imports'); | 
					
						
							|  |  |  | const addFrontmatter = require('./plugins/add-frontmatter'); | 
					
						
							|  |  |  | const addText = require('./plugins/add-text'); | 
					
						
							|  |  |  | const addVideoQuestion = require('./plugins/add-video-question'); | 
					
						
							|  |  |  | const addSeed = require('./plugins/add-seed'); | 
					
						
							|  |  |  | const addSolution = require('./plugins/add-solution'); | 
					
						
							|  |  |  | const tableAndStrikeThrough = require('./plugins/table-and-strikethrough'); | 
					
						
							|  |  |  | const unified = require('unified'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // by convention, anything that adds to file.data has the name add<name>.
 | 
					
						
							|  |  |  | const processor = unified() | 
					
						
							|  |  |  |   // add the remark parser
 | 
					
						
							|  |  |  |   .use(remark) | 
					
						
							|  |  |  |   // modify the parser so that Github flavour tables and strikethroughs get
 | 
					
						
							|  |  |  |   // converted to 'delete' nodes
 | 
					
						
							|  |  |  |   .use(tableAndStrikeThrough) | 
					
						
							|  |  |  |   // directives are parsed into 'leafDirective' nodes and used for imports
 | 
					
						
							|  |  |  |   .use(directive) | 
					
						
							|  |  |  |   // convert the text at the top of the document (surrounded by ---) into a
 | 
					
						
							|  |  |  |   // 'yaml' node
 | 
					
						
							|  |  |  |   .use(frontmatter, ['yaml']) | 
					
						
							|  |  |  |   // extract the content from that 'yaml' node
 | 
					
						
							|  |  |  |   .use(addFrontmatter) | 
					
						
							|  |  |  |   // Any imports will be replaced (in the tree) with
 | 
					
						
							|  |  |  |   // the sub-tree of the target file. e.g.
 | 
					
						
							|  |  |  |   // ::import{component="Script" from="./file.path" }
 | 
					
						
							|  |  |  |   // means that file.path's tree will be inserted wherever
 | 
					
						
							|  |  |  |   // ::use{component="Script"}
 | 
					
						
							|  |  |  |   // appears.
 | 
					
						
							|  |  |  |   .use(replaceImports) | 
					
						
							| 
									
										
										
										
											2021-02-22 04:44:12 +01:00
										 |  |  |   // the final five 'add' plugins insert content into file.data
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |   // TODO: rename test->hint everywhere? It should make things easier to reason
 | 
					
						
							|  |  |  |   // about.
 | 
					
						
							|  |  |  |   .use(addSeed) | 
					
						
							| 
									
										
										
										
											2021-02-22 04:44:12 +01:00
										 |  |  |   .use(addSolution) | 
					
						
							|  |  |  |   // the directives will have been parsed and used by this point, any remaining
 | 
					
						
							|  |  |  |   // 'directives' will be from text like the css selector :root. These should be
 | 
					
						
							|  |  |  |   // converted back to text before they're added to the challenge object.
 | 
					
						
							|  |  |  |   .use(restoreDirectives) | 
					
						
							|  |  |  |   .use(addVideoQuestion) | 
					
						
							|  |  |  |   .use(addTests) | 
					
						
							|  |  |  |   .use(addText, ['description', 'instructions']); | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | exports.parseMD = function parseMD(filename) { | 
					
						
							|  |  |  |   return new Promise((resolve, reject) => { | 
					
						
							|  |  |  |     const file = readSync(filename); | 
					
						
							|  |  |  |     const tree = processor.parse(file); | 
					
						
							|  |  |  |     processor.run(tree, file, function(err, node, file) { | 
					
						
							| 
									
										
										
										
											2021-02-22 10:42:36 +01:00
										 |  |  |       if (!err) { | 
					
						
							|  |  |  |         delete file.contents; | 
					
						
							|  |  |  |         resolve(file.data); | 
					
						
							| 
									
										
										
										
											2021-02-27 08:24:38 +01:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         err.message += ' in file ' + filename; | 
					
						
							|  |  |  |         reject(err); | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }; |