diff --git a/tools/challenge-parser/package-lock.json b/tools/challenge-parser/package-lock.json
index 1e9ccf016c..8045b11c77 100644
--- a/tools/challenge-parser/package-lock.json
+++ b/tools/challenge-parser/package-lock.json
@@ -287,17 +287,35 @@
}
},
"mdast-util-directive": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-1.0.0.tgz",
- "integrity": "sha512-04nOvmHrQfcgPQDAn9x0gW05vhqXmkGPP9G7o8BE+7Oy16oyTAgJpJyVFTscPyEzfsP7p7LSKJAXWqTCBvPjuw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-1.0.1.tgz",
+ "integrity": "sha512-VuO1za7BMtWMg8KA8eZrTBorEnCOOW5CXfIuNzUXe7YPie/wLgmNk/jxLMY8m+mzuqnO5eN0JuvlgFtO9EJpbQ==",
"requires": {
- "mdast-util-to-markdown": "^0.5.0",
+ "mdast-util-to-markdown": "^0.6.0",
"parse-entities": "^2.0.0",
"repeat-string": "^1.0.0",
"stringify-entities": "^3.1.0",
"unist-util-visit-parents": "^3.0.0"
},
"dependencies": {
+ "mdast-util-to-markdown": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.1.tgz",
+ "integrity": "sha512-4qJtZ0qdyYeexAXoOZiU0uHIFVncJAmCkHkSluAsvDaVWODtPyNEo9I1ns0T4ulxu2EHRH5u/bt1cV0pdHCX+A==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "longest-streak": "^2.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "parse-entities": "^2.0.0",
+ "repeat-string": "^1.0.0",
+ "zwitch": "^1.0.0"
+ }
+ },
+ "mdast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w=="
+ },
"unist-util-visit-parents": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
@@ -417,12 +435,23 @@
}
},
"micromark-extension-directive": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-1.0.0.tgz",
- "integrity": "sha512-6FjvznI5GpUysZqGtTEMeDaC/D3FdWFVc3CC5gDZB3fBtqiaIRBhCNg4fbqvrFSC0T2eqRbO2dJ7ZFU86gAtEQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-1.1.1.tgz",
+ "integrity": "sha512-xkv00i9brg3LkOMleJc/mlDZlb2TF2TomSS0D4AVhWVDZx4OmuYxFlqtKHuiDXXiVp4mhcZfHsuWdvELdT7I9g==",
"requires": {
- "micromark": "~2.10.0",
+ "micromark": "~2.11.0",
"parse-entities": "^2.0.0"
+ },
+ "dependencies": {
+ "micromark": {
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz",
+ "integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==",
+ "requires": {
+ "debug": "^4.0.0",
+ "parse-entities": "^2.0.0"
+ }
+ }
}
},
"micromark-extension-frontmatter": {
@@ -568,6 +597,34 @@
"mdast-util-from-markdown": "^0.8.0"
}
},
+ "remark-stringify": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz",
+ "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==",
+ "requires": {
+ "mdast-util-to-markdown": "^0.6.0"
+ },
+ "dependencies": {
+ "mdast-util-to-markdown": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.1.tgz",
+ "integrity": "sha512-4qJtZ0qdyYeexAXoOZiU0uHIFVncJAmCkHkSluAsvDaVWODtPyNEo9I1ns0T4ulxu2EHRH5u/bt1cV0pdHCX+A==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "longest-streak": "^2.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "parse-entities": "^2.0.0",
+ "repeat-string": "^1.0.0",
+ "zwitch": "^1.0.0"
+ }
+ },
+ "mdast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w=="
+ }
+ }
+ },
"repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
diff --git a/tools/challenge-parser/package.json b/tools/challenge-parser/package.json
index f108954f9c..32cefa780d 100644
--- a/tools/challenge-parser/package.json
+++ b/tools/challenge-parser/package.json
@@ -23,6 +23,7 @@
"remark-frontmatter": "^3.0.0",
"remark-html": "^12.0.0",
"remark-parse": "^9.0.0",
+ "remark-stringify": "^9.0.1",
"to-vfile": "^5.0.1",
"unified": "^7.0.0",
"unist-util-find": "^1.0.1",
diff --git a/tools/challenge-parser/parser/__fixtures__/ast-directives.json b/tools/challenge-parser/parser/__fixtures__/ast-directives.json
new file mode 100644
index 0000000000..5d719f653d
--- /dev/null
+++ b/tools/challenge-parser/parser/__fixtures__/ast-directives.json
@@ -0,0 +1,185 @@
+{
+ "type": "root",
+ "children": [
+ {
+ "type": "heading",
+ "depth": 1,
+ "children": [
+ {
+ "type": "text",
+ "value": "--description--",
+ "position": {
+ "start": { "line": 1, "column": 3, "offset": 2 },
+ "end": { "line": 1, "column": 18, "offset": 17 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 1, "column": 1, "offset": 0 },
+ "end": { "line": 1, "column": 18, "offset": 17 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "textDirective",
+ "name": "root",
+ "attributes": {},
+ "children": [],
+ "position": {
+ "start": { "line": 3, "column": 1, "offset": 19 },
+ "end": { "line": 3, "column": 6, "offset": 24 }
+ }
+ },
+ {
+ "type": "text",
+ "value": " appears, ",
+ "position": {
+ "start": { "line": 3, "column": 6, "offset": 24 },
+ "end": { "line": 3, "column": 16, "offset": 34 }
+ }
+ },
+ {
+ "type": "textDirective",
+ "name": "import",
+ "attributes": {},
+ "children": [],
+ "position": {
+ "start": { "line": 3, "column": 16, "offset": 34 },
+ "end": { "line": 3, "column": 23, "offset": 41 }
+ }
+ },
+ {
+ "type": "text",
+ "value": " appears",
+ "position": {
+ "start": { "line": 3, "column": 23, "offset": 41 },
+ "end": { "line": 3, "column": 31, "offset": 49 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 3, "column": 1, "offset": 19 },
+ "end": { "line": 3, "column": 31, "offset": 49 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "the next paragraph should appear",
+ "position": {
+ "start": { "line": 5, "column": 1, "offset": 51 },
+ "end": { "line": 5, "column": 33, "offset": 83 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 5, "column": 1, "offset": 51 },
+ "end": { "line": 5, "column": 33, "offset": 83 }
+ }
+ },
+ {
+ "type": "leafDirective",
+ "name": "import",
+ "attributes": {},
+ "children": [],
+ "position": {
+ "start": { "line": 7, "column": 1, "offset": 85 },
+ "end": { "line": 7, "column": 9, "offset": 93 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "even though it's an import directive, but if we use the full syntax ",
+ "position": {
+ "start": { "line": 9, "column": 1, "offset": 95 },
+ "end": { "line": 9, "column": 58, "offset": 152 }
+ }
+ },
+ {
+ "type": "inlineCode",
+ "value": "::directive-name{attr=\"name\" attr2=\"a/path\"}",
+ "position": {
+ "start": { "line": 9, "column": 58, "offset": 152 },
+ "end": { "line": 9, "column": 100, "offset": 194 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 9, "column": 1, "offset": 95 },
+ "end": { "line": 9, "column": 100, "offset": 194 }
+ }
+ },
+ {
+ "type": "leafDirective",
+ "name": "import",
+ "attributes": { "component": "name", "from": "script.md" },
+ "children": [],
+ "position": {
+ "start": { "line": 11, "column": 1, "offset": 196 },
+ "end": { "line": 11, "column": 44, "offset": 239 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "it goes.",
+ "position": {
+ "start": { "line": 13, "column": 1, "offset": 241 },
+ "end": { "line": 13, "column": 9, "offset": 249 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 13, "column": 1, "offset": 241 },
+ "end": { "line": 13, "column": 9, "offset": 249 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "::: name [inline-content] {key=val}\na container directive\n:::",
+ "position": {
+ "start": { "line": 15, "column": 1, "offset": 251 },
+ "end": { "line": 17, "column": 4, "offset": 312 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 15, "column": 1, "offset": 251 },
+ "end": { "line": 17, "column": 4, "offset": 312 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": ":::",
+ "position": {
+ "start": { "line": 19, "column": 1, "offset": 314 },
+ "end": { "line": 19, "column": 4, "offset": 317 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 19, "column": 1, "offset": 314 },
+ "end": { "line": 19, "column": 4, "offset": 317 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 1, "column": 1, "offset": 0 },
+ "end": { "line": 20, "column": 1, "offset": 318 }
+ }
+}
diff --git a/tools/challenge-parser/parser/__fixtures__/ast-imports-extra.json b/tools/challenge-parser/parser/__fixtures__/ast-imports-extra.json
new file mode 100644
index 0000000000..d37e08b01c
--- /dev/null
+++ b/tools/challenge-parser/parser/__fixtures__/ast-imports-extra.json
@@ -0,0 +1,321 @@
+{
+ "type": "root",
+ "children": [
+ {
+ "type": "leafDirective",
+ "name": "import",
+ "attributes": { "component": "Script", "from": "./script.md" },
+ "children": [],
+ "position": {
+ "start": { "line": 1, "column": 1, "offset": 0 },
+ "end": { "line": 1, "column": 49, "offset": 48 }
+ }
+ },
+ {
+ "type": "leafDirective",
+ "name": "import",
+ "attributes": { "component": "Second", "from": "./script-two.md" },
+ "children": [],
+ "position": {
+ "start": { "line": 2, "column": 1, "offset": 49 },
+ "end": { "line": 2, "column": 53, "offset": 101 }
+ }
+ },
+ {
+ "type": "leafDirective",
+ "name": "import",
+ "attributes": {},
+ "children": [],
+ "position": {
+ "start": { "line": 3, "column": 1, "offset": 102 },
+ "end": { "line": 3, "column": 9, "offset": 110 }
+ }
+ },
+ {
+ "type": "heading",
+ "depth": 1,
+ "children": [
+ {
+ "type": "text",
+ "value": "--description--",
+ "position": {
+ "start": { "line": 5, "column": 3, "offset": 114 },
+ "end": { "line": 5, "column": 18, "offset": 129 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 5, "column": 1, "offset": 112 },
+ "end": { "line": 5, "column": 18, "offset": 129 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "Paragraph 1 ::import",
+ "position": {
+ "start": { "line": 7, "column": 1, "offset": 131 },
+ "end": { "line": 7, "column": 21, "offset": 151 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 7, "column": 1, "offset": 131 },
+ "end": { "line": 7, "column": 21, "offset": 151 }
+ }
+ },
+ {
+ "type": "code",
+ "lang": "html",
+ "meta": null,
+ "value": "code example",
+ "position": {
+ "start": { "line": 9, "column": 1, "offset": 153 },
+ "end": { "line": 11, "column": 4, "offset": 177 }
+ }
+ },
+ {
+ "type": "heading",
+ "depth": 1,
+ "children": [
+ {
+ "type": "text",
+ "value": "--instructions--",
+ "position": {
+ "start": { "line": 13, "column": 3, "offset": 181 },
+ "end": { "line": 13, "column": 19, "offset": 197 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 13, "column": 1, "offset": 179 },
+ "end": { "line": 13, "column": 19, "offset": 197 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "Paragraph 0",
+ "position": {
+ "start": { "line": 15, "column": 1, "offset": 199 },
+ "end": { "line": 15, "column": 12, "offset": 210 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 15, "column": 1, "offset": 199 },
+ "end": { "line": 15, "column": 12, "offset": 210 }
+ }
+ },
+ {
+ "type": "code",
+ "lang": "html",
+ "meta": null,
+ "value": "code example 0",
+ "position": {
+ "start": { "line": 17, "column": 1, "offset": 212 },
+ "end": { "line": 19, "column": 4, "offset": 238 }
+ }
+ },
+ {
+ "type": "heading",
+ "depth": 1,
+ "children": [
+ {
+ "type": "text",
+ "value": "--hints--",
+ "position": {
+ "start": { "line": 21, "column": 3, "offset": 242 },
+ "end": { "line": 21, "column": 12, "offset": 251 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 21, "column": 1, "offset": 240 },
+ "end": { "line": 21, "column": 12, "offset": 251 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "First hint",
+ "position": {
+ "start": { "line": 23, "column": 1, "offset": 253 },
+ "end": { "line": 23, "column": 11, "offset": 263 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 23, "column": 1, "offset": 253 },
+ "end": { "line": 23, "column": 11, "offset": 263 }
+ }
+ },
+ {
+ "type": "code",
+ "lang": "js",
+ "meta": null,
+ "value": "// test code",
+ "position": {
+ "start": { "line": 25, "column": 1, "offset": 265 },
+ "end": { "line": 27, "column": 4, "offset": 287 }
+ }
+ },
+ {
+ "type": "paragraph",
+ "children": [
+ {
+ "type": "text",
+ "value": "Second hint with ",
+ "position": {
+ "start": { "line": 29, "column": 1, "offset": 289 },
+ "end": { "line": 29, "column": 18, "offset": 306 }
+ }
+ },
+ {
+ "type": "html",
+ "value": "",
+ "position": {
+ "start": { "line": 29, "column": 18, "offset": 306 },
+ "end": { "line": 29, "column": 24, "offset": 312 }
+ }
+ },
+ {
+ "type": "text",
+ "value": "code",
+ "position": {
+ "start": { "line": 29, "column": 24, "offset": 312 },
+ "end": { "line": 29, "column": 28, "offset": 316 }
+ }
+ },
+ {
+ "type": "html",
+ "value": "
",
+ "position": {
+ "start": { "line": 29, "column": 28, "offset": 316 },
+ "end": { "line": 29, "column": 35, "offset": 323 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 29, "column": 1, "offset": 289 },
+ "end": { "line": 29, "column": 35, "offset": 323 }
+ }
+ },
+ {
+ "type": "code",
+ "lang": "js",
+ "meta": null,
+ "value": "// more test code",
+ "position": {
+ "start": { "line": 31, "column": 1, "offset": 325 },
+ "end": { "line": 33, "column": 4, "offset": 352 }
+ }
+ },
+ {
+ "type": "heading",
+ "depth": 1,
+ "children": [
+ {
+ "type": "text",
+ "value": "--seed--",
+ "position": {
+ "start": { "line": 36, "column": 3, "offset": 357 },
+ "end": { "line": 36, "column": 11, "offset": 365 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 36, "column": 1, "offset": 355 },
+ "end": { "line": 36, "column": 11, "offset": 365 }
+ }
+ },
+ {
+ "type": "heading",
+ "depth": 2,
+ "children": [
+ {
+ "type": "text",
+ "value": "--seed-contents--",
+ "position": {
+ "start": { "line": 38, "column": 4, "offset": 370 },
+ "end": { "line": 38, "column": 21, "offset": 387 }
+ }
+ }
+ ],
+ "position": {
+ "start": { "line": 38, "column": 1, "offset": 367 },
+ "end": { "line": 38, "column": 21, "offset": 387 }
+ }
+ },
+ {
+ "type": "code",
+ "lang": "html",
+ "meta": null,
+ "value": "\n
code
+
+```js
+// more test code
+```
+
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+```
+
+```css
+body {
+ background: green;
+}
+```
+
+::use{component="Second"}
+
+::id{#custom-name}
+
+```js
+var x = 'y';
+```
+
+::use{component="Script"}
diff --git a/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap b/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap
index ea04e9de46..2f4f15130b 100644
--- a/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap
+++ b/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap
@@ -1,5 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`challenge parser it should not parse directives we do not use 1`] = `
+Object {
+ "description": ":root appears, :import appears
+the next paragraph should appear
+::import +even though it's an import directive, but if we use the full syntax ::directive-name{attr=\\"name\\" attr2=\\"a/path\\"}
it goes.
+::: name [inline-content] {key=val} +a container directive +:::
+