chore: import upstream snapshot with attribution
CD - Docker - GHCR Images / Build and Push Images (push) Waiting to run
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
CD - Docker - GHCR Images / Build and Push Images (push) Waiting to run
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
<code> code in </code> code tags _emphasis_ followed by <div><span>some nested html </span></div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Paragraph 1
|
||||
|
||||
Third _hint_ with <code>code</code> and `inline code`
|
||||
@@ -0,0 +1,13 @@
|
||||
const { join } = require('path');
|
||||
const remark = require('remark');
|
||||
const directive = require('remark-directive');
|
||||
const frontmatter = require('remark-frontmatter');
|
||||
const { read } = require('to-vfile');
|
||||
|
||||
const parseFixture = async (filename) => remark()
|
||||
.use(directive)
|
||||
.use(frontmatter, ['yaml'])
|
||||
.parse(await read(join(__dirname, filename)));
|
||||
|
||||
|
||||
module.exports = parseFixture;
|
||||
@@ -0,0 +1,176 @@
|
||||
# --description--
|
||||
|
||||
When you add a lower rank heading element to the page, it's implied that you're starting a new subsection.
|
||||
|
||||
After the last <code>h2</code> element of the second `section` element, add an `h3` element with the text `Things cats love:`.
|
||||
|
||||
<blockquote>
|
||||
<p>Some text in a blockquote</p>
|
||||
<p>
|
||||
Some text in a blockquote, with <code>code</code>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Do something with the `code`.
|
||||
|
||||
To test that adjacent tags are handled correctly:
|
||||
|
||||
a bit of <code>code</code> <tag>with more after a space</tag> and another pair of <strong>elements</strong> <em>with a space</em>
|
||||
|
||||
# --hints--
|
||||
|
||||
The second `section` element appears to be missing or does not have both an opening and closing tag.
|
||||
|
||||
```js
|
||||
assert(
|
||||
document.querySelectorAll('main > section')[1] &&
|
||||
code.match(/\<\/section>/g).length == 2
|
||||
);
|
||||
```
|
||||
|
||||
There should be an `h3` element right above the second `section` element's closing tag.
|
||||
|
||||
```js
|
||||
assert(
|
||||
document.querySelectorAll('main > section')[1].lastElementChild.nodeName ===
|
||||
'H3'
|
||||
);
|
||||
```
|
||||
|
||||
The `h3` element right above the second `section` element's closing tag should have the text `Things cats love:`. Make sure to include the colon at the end of the text.
|
||||
|
||||
```js
|
||||
assert(
|
||||
document
|
||||
.querySelectorAll('main > section')[1]
|
||||
.lastElementChild.innerText.toLowerCase()
|
||||
.replace(/\s+/g, ' ') === 'things cats love:'
|
||||
);
|
||||
```
|
||||
|
||||
There should be an `h2` element with the text `Cat Lists` above the last `h3` element that is nested in the last `section` element'. You may have accidentally deleted the `h2` element.
|
||||
|
||||
```js
|
||||
const secondSectionLastElemNode = document.querySelectorAll('main > section')[1]
|
||||
.lastElementChild;
|
||||
assert(
|
||||
secondSectionLastElemNode.nodeName === 'H3' &&
|
||||
secondSectionLastElemNode.previousElementSibling.innerText
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, ' ') === 'cat lists'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Cat Photos</h2>
|
||||
<!-- TODO: Add link to cat photos -->
|
||||
<p>
|
||||
Click here to view more
|
||||
<a target="_blank" href="https://www.freecodecamp.org/cat-photos"
|
||||
>cat photos</a
|
||||
>.
|
||||
</p>
|
||||
<a href="https://www.freecodecamp.org/cat-photos"
|
||||
><img
|
||||
src="https://bit.ly/fcc-relaxing-cat"
|
||||
alt="A cute orange cat lying on its back."
|
||||
/></a>
|
||||
</section>
|
||||
--fcc-editable-region--
|
||||
<section>
|
||||
<h2>Cat Lists</h2>
|
||||
</section>
|
||||
--fcc-editable-region--
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#final-key}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Cat Photos</h2>
|
||||
<!-- TODO: Add link to cat photos -->
|
||||
<p>
|
||||
Click here to view more
|
||||
<a target="_blank" href="https://www.freecodecamp.org/cat-photos"
|
||||
>cat photos</a
|
||||
>.
|
||||
</p>
|
||||
<a href="https://www.freecodecamp.org/cat-photos"
|
||||
><img
|
||||
src="https://bit.ly/fcc-relaxing-cat"
|
||||
alt="A cute orange cat lying on its back."
|
||||
/></a>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Cat Lists</h2>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#final-key}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
# --description--
|
||||
|
||||
This challenge has a scene.
|
||||
|
||||
# --scene--
|
||||
|
||||
```json
|
||||
{
|
||||
"setup": {
|
||||
"background": "company2-center.png",
|
||||
"characters": [
|
||||
{
|
||||
"character": "Maria",
|
||||
"position": { "x": 50, "y": 0, "z": 1.5 },
|
||||
"opacity": 0
|
||||
}
|
||||
],
|
||||
"audio": {
|
||||
"filename": "1.1-1.mp3",
|
||||
"startTime": 1,
|
||||
"startTimestamp": 2.6,
|
||||
"finishTimestamp": 4
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"character": "Maria",
|
||||
"opacity": 1,
|
||||
"startTime": 0
|
||||
},
|
||||
{
|
||||
"character": "Maria",
|
||||
"startTime": 0.7,
|
||||
"finishTime": 2.4,
|
||||
"dialogue": {
|
||||
"text": "I'm Maria, the team lead.",
|
||||
"align": "center"
|
||||
}
|
||||
},
|
||||
{
|
||||
"character": "Maria",
|
||||
"opacity": 0,
|
||||
"startTime": 3.4
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
```css
|
||||
div {
|
||||
background: red
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
```js
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
const element = array[index];
|
||||
// imported from script.md
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,89 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-all--
|
||||
|
||||
```js
|
||||
// after all code
|
||||
function teardown() {
|
||||
return 'cleaned up';
|
||||
}
|
||||
teardown();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-each--
|
||||
|
||||
```js
|
||||
// after each code
|
||||
function cleanup() {
|
||||
return 'cleaned up';
|
||||
}
|
||||
cleanup();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-all--
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-each--
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-each--
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-all--
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-each--
|
||||
|
||||
```js
|
||||
// before each code
|
||||
function setup() {
|
||||
return 'initialized';
|
||||
}
|
||||
setup();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-all--
|
||||
|
||||
```js
|
||||
// before all code
|
||||
function foo() {
|
||||
return 'bar';
|
||||
}
|
||||
foo();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
First hint
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`BLANK BLANK`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`你 (nǐ)`
|
||||
@@ -0,0 +1,17 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`我 (wǒ) BLANK UI 设计师 (shè jì shī) 。`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`是 (shì)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback text.
|
||||
|
||||
# --explanation--
|
||||
|
||||
Explanation text.
|
||||
@@ -0,0 +1,9 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`你好 (nǐ hǎo)`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`你`
|
||||
@@ -0,0 +1,9 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`BLANK hǎo`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`nǐ`
|
||||
@@ -0,0 +1,9 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`BLANK好`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`你 (nǐ)`
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`BLANK 好 (hǎo) BLANK`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`你`
|
||||
|
||||
---
|
||||
|
||||
`nǐ`
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
lang: zh-CN
|
||||
inputType: pinyin-to-hanzi
|
||||
---
|
||||
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`BLANK BLANK,BLANK 是王华 (shì Wang Hua),请问你 (qǐng wèn nǐ) BLANK 什么名字 (shén me míng zi)?`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`你 (nǐ)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback text containing `汉字 (hàn zì)`.
|
||||
|
||||
---
|
||||
|
||||
`好 (hǎo)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
This means "good" or "well".
|
||||
|
||||
---
|
||||
|
||||
`我 (wǒ)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
This means "I".
|
||||
|
||||
---
|
||||
|
||||
`叫 (jiào)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
This means "to be called".
|
||||
|
||||
# --explanation--
|
||||
|
||||
Explanation text containing `汉字 (hàn zì)`.
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: test-with-chinese-mcq
|
||||
title: Ruby Test
|
||||
challengeType: 19
|
||||
lang: zh-CN
|
||||
---
|
||||
|
||||
# --instructions--
|
||||
|
||||
Instructions containing `汉字 (hàn zì)`.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question text containing `汉字 (hàn zì)`.
|
||||
|
||||
## --answers--
|
||||
|
||||
`你好 (nǐ hǎo)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback text.
|
||||
|
||||
---
|
||||
|
||||
`请 (qǐng)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
`请 (qǐng)` is not correct.
|
||||
|
||||
---
|
||||
|
||||
`请问 (qǐng wèn)`
|
||||
|
||||
---
|
||||
|
||||
`问 (wèn)`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback text.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
|
||||
# --explanation--
|
||||
|
||||
`我是 (wǒ shì) Web 开发者 (kāi fā zhě)。` – I am a web developer.
|
||||
|
||||
`你好 (nǐ hǎo),我是王华 (wǒ shì Wang Hua),请问你叫什么名字 (qǐng wèn nǐ jiào shén me míng zi)?` – Hello, I am Wang Hua, may I ask what your name is?
|
||||
@@ -0,0 +1,87 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 1 with `中文 (zhōng wén)`
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "7.3-1.mp3",
|
||||
"startTimestamp": 24.7,
|
||||
"finishTimestamp": 26.2
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"character": "Wang Hua",
|
||||
"text": "你好 (nǐ hǎo)。"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 1, distractor 1 with `中文 (zhōng wén)`
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 1, distractor 2 with `中文 (zhōng wén)`
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 1, distractor 3 with `中文 (zhōng wén)`
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 1, answer with `中文 (zhōng wén)`
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 2 with `中文`
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 2, distractor 1 with `中文`
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 2, distractor 2 with `中文`
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 2, distractor 3 with `中文`
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 2, answer with `中文`
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 3 with `zhōng wén`
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 3, distractor 1 with `zhōng wén`
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 3, distractor 2 with `zhōng wén`
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 3, distractor 3 with `zhōng wén`
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 3, answer with `zhōng wén`
|
||||
@@ -0,0 +1,35 @@
|
||||
# --description--
|
||||
|
||||
This challenge has a Chinese scene with plain hanzi (no pinyin).
|
||||
|
||||
# --scene--
|
||||
|
||||
```json
|
||||
{
|
||||
"setup": {
|
||||
"background": "company1-reception.png",
|
||||
"characters": [
|
||||
{
|
||||
"character": "Wang Hua",
|
||||
"position": { "x": 50, "y": 15, "z": 1.4 },
|
||||
"opacity": 0
|
||||
}
|
||||
],
|
||||
"audio": {
|
||||
"filename": "test.mp3",
|
||||
"startTime": 1
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"character": "Wang Hua",
|
||||
"startTime": 1,
|
||||
"finishTime": 2,
|
||||
"dialogue": {
|
||||
"text": "你好,世界。",
|
||||
"align": "center"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
# --description--
|
||||
|
||||
This challenge has a Chinese scene with hanzi-pinyin pairs.
|
||||
|
||||
# --scene--
|
||||
|
||||
```json
|
||||
{
|
||||
"setup": {
|
||||
"background": "company1-reception.png",
|
||||
"characters": [
|
||||
{
|
||||
"character": "Wang Hua",
|
||||
"position": { "x": 50, "y": 15, "z": 1.4 },
|
||||
"opacity": 0
|
||||
}
|
||||
],
|
||||
"audio": {
|
||||
"filename": "ZH_A1_welcome_hello_world.mp3",
|
||||
"startTime": 1,
|
||||
"startTimestamp": 5.18,
|
||||
"finishTimestamp": 6.71
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"character": "Wang Hua",
|
||||
"startTime": 1,
|
||||
"finishTime": 2.53,
|
||||
"dialogue": {
|
||||
"text": "你好 (nǐ hǎo),世界 (shì jiè)。",
|
||||
"align": "center"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
# --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"}`
|
||||
|
||||
::import{component="name" from="script.md"}
|
||||
|
||||
it goes.
|
||||
|
||||
::: name [inline-content] {key=val}
|
||||
a container directive
|
||||
:::
|
||||
@@ -0,0 +1,84 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
--fcc-editable-region-- --fcc-editable-region--
|
||||
background: green;
|
||||
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
--fcc-editable-region--
|
||||
background: green;
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,64 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
This section intentionally has no `## --seed-contents--`.
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
# --description--
|
||||
|
||||
This is a test file for empty interactive elements.
|
||||
|
||||
# --interactive--
|
||||
|
||||
no subsections
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
id: with-en-us-mcq
|
||||
title: en-US MCQ
|
||||
challengeType: 19
|
||||
lang: en-US
|
||||
---
|
||||
|
||||
# --instructions--
|
||||
|
||||
Instructions containing `some code`.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question text containing `highlighted text`.
|
||||
|
||||
## --answers--
|
||||
|
||||
`correct answer`
|
||||
|
||||
---
|
||||
|
||||
`wrong answer`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback text containing `highlighted text`.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
|
||||
# --explanation--
|
||||
|
||||
Explanation text containing `highlighted text`.
|
||||
@@ -0,0 +1,44 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
--fcc-editable-region--
|
||||
background: white;
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
id: with-es-mcq
|
||||
title: Spanish MCQ
|
||||
challengeType: 19
|
||||
lang: es
|
||||
---
|
||||
|
||||
# --instructions--
|
||||
|
||||
Instructions containing `texto resaltado`.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question text containing `texto resaltado`.
|
||||
|
||||
## --answers--
|
||||
|
||||
`correct answer`
|
||||
|
||||
---
|
||||
|
||||
`wrong answer`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback text containing `texto resaltado`.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
|
||||
# --explanation--
|
||||
|
||||
Explanation text containing `texto resaltado`.
|
||||
@@ -0,0 +1,83 @@
|
||||
# --description--
|
||||
|
||||
# this should still be inside --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
# --description--
|
||||
|
||||
In English, to check or confirm something people sometimes use tag questions. For example, `You are a programmer, right?` Here, `right?` is used as a tag to check or confirm the previous statement.
|
||||
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`A sentence BLANK paragraph 1`
|
||||
`not enough newlines, so no paragraph 2`
|
||||
|
||||
Sentence in BLANK 2
|
||||
|
||||
## --blanks--
|
||||
|
||||
`are`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Pay attention to the verb in the sentence.
|
||||
|
||||
---
|
||||
|
||||
`right`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Pay attention to the verb in the sentence.
|
||||
@@ -0,0 +1,27 @@
|
||||
# --description--
|
||||
|
||||
In English, to check or confirm something people sometimes use tag questions. For example, `You are a programmer, right?` Here, `right?` is used as a tag to check or confirm the previous statement.
|
||||
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`A sentence BLANK paragraph 1`
|
||||
|
||||
Sentence in BLANK 2
|
||||
|
||||
## --blanks--
|
||||
|
||||
`are`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Pay attention to the verb in the sentence.
|
||||
|
||||
---
|
||||
|
||||
`right`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Pay attention to the verb in the sentence.
|
||||
@@ -0,0 +1,29 @@
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`Sure thing! BLANK _ _.`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`I'd`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback 1
|
||||
|
||||
## --blanks--
|
||||
|
||||
`love`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback 2
|
||||
|
||||
## --blanks--
|
||||
|
||||
`to`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback 3
|
||||
@@ -0,0 +1,19 @@
|
||||
# --description--
|
||||
|
||||
In English, when making introductions or identifying someone, you use the verb `to be`. In this case, `You are` is used to address the person Maria is talking to and affirmatively identify their occupation.
|
||||
|
||||
Maria is introducing herself and confirming Tom's job role. `Are` is used in the present affirmative to make a statement.
|
||||
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`Hello, You BLANK the new graphic designer, right?`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`are`
|
||||
|
||||
### --feedback--
|
||||
|
||||
The verb `to be` is an irregular verb. When conjugated with the pronoun `you`, `be` becomes `are`. For example: `You are an English learner.`
|
||||
@@ -0,0 +1,27 @@
|
||||
# --description--
|
||||
|
||||
In English, to check or confirm something people sometimes use tag questions. For example, `You are a programmer, right?` Here, `right?` is used as a tag to check or confirm the previous statement.
|
||||
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`A sentence BLANK paragraph 1`
|
||||
|
||||
`Sentence in BLANK 2`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`are`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Pay attention to the verb in the sentence.
|
||||
|
||||
---
|
||||
|
||||
`right`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Pay attention to the verb in the sentence.
|
||||
@@ -0,0 +1,31 @@
|
||||
# --description--
|
||||
|
||||
In English, when making introductions or identifying someone, you use the verb `to be`. In this case, `You are` is used to address the person Maria is talking to and affirmatively identify their occupation.
|
||||
|
||||
Maria is introducing herself and confirming Tom's job role. `Are` is used in the present affirmative to make a statement.
|
||||
|
||||
# --fillInTheBlank--
|
||||
|
||||
## --sentence--
|
||||
|
||||
`Hello, You BLANK the new graphic designer, BLANK? BLANK to meet you!`
|
||||
|
||||
## --blanks--
|
||||
|
||||
`are`
|
||||
|
||||
### --feedback--
|
||||
|
||||
The verb `to be` is an irregular verb. When conjugated with the pronoun `you`, `be` becomes `are`. For example: `You are an English learner.`
|
||||
|
||||
---
|
||||
|
||||
`right`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback 2
|
||||
|
||||
---
|
||||
|
||||
`Nice`
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: bd7123c8c441eddfaeb5bdef
|
||||
title: Say Hello to HTML Elements
|
||||
challengeType: 0
|
||||
isHidden: false
|
||||
videoUrl: 'https://scrimba.com/p/pVMPUv/cE8Gpt2'
|
||||
forumTopicId: 18276
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,86 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1 ~~Strikethrough text~~. https://should.not.be.autolinked
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
| example | of a |
|
||||
| --- | --- |
|
||||
| gfm | table |
|
||||
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
::id{#html-key}
|
||||
|
||||

|
||||
|
||||
Paragraph with an image  in it.
|
||||
@@ -0,0 +1,61 @@
|
||||
::import{component="Script" from="./script.md" }
|
||||
::import{component="Second" from="./script-two.md" }
|
||||
::import
|
||||
|
||||
# --description--
|
||||
|
||||
Paragraph 1 ::import
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::use{component="Second"}
|
||||
|
||||
::id{#custom-name}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
::use{component="Script"}
|
||||
@@ -0,0 +1,60 @@
|
||||
::import{component="Script" from="./script.md" }
|
||||
::import{component="Second" from="./script-two.md" }
|
||||
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::use{component="Second"}
|
||||
|
||||
::id{#custom-name}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
::use{component="Script"}
|
||||
@@ -0,0 +1,57 @@
|
||||
::import{component="Script" from="./script.md" }
|
||||
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#custom-name}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
::use{component="Script"}
|
||||
@@ -0,0 +1,17 @@
|
||||
# --interactive--
|
||||
|
||||
Normal markdown
|
||||
|
||||
```html
|
||||
<div>This is NOT an interactive element</div>
|
||||
```
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
console.log('Interactive JS');
|
||||
```
|
||||
|
||||
non-code md is not allowed
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,43 @@
|
||||
# --interactive--
|
||||
|
||||
Normal markdown
|
||||
|
||||
```html
|
||||
<div>This is NOT an interactive element</div>
|
||||
```
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
console.log('Interactive JS');
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```html
|
||||
<div>This is an interactive element</div>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
```html
|
||||
<div>This is not interactive</div>
|
||||
```
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```html
|
||||
<div>This is an interactive element</div>
|
||||
```
|
||||
|
||||
```js
|
||||
console.log('Interactive JS');
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
```html
|
||||
<div>This is also not interactive</div>
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-all--
|
||||
|
||||
```js
|
||||
// after all code
|
||||
function teardown() {
|
||||
return 'cleaned up';
|
||||
}
|
||||
teardown();
|
||||
```
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-each--
|
||||
|
||||
```js
|
||||
// after each code
|
||||
function cleanup() {
|
||||
return 'cleaned up';
|
||||
}
|
||||
cleanup();
|
||||
```
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-each--
|
||||
|
||||
```js
|
||||
// before each code
|
||||
function setup() {
|
||||
return 'initialized';
|
||||
}
|
||||
setup();
|
||||
```
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-all--
|
||||
|
||||
```js
|
||||
// before all code
|
||||
function foo() {
|
||||
return 'bar';
|
||||
}
|
||||
foo();
|
||||
```
|
||||
|
||||
gubbins
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,57 @@
|
||||
::import{component="Script" from="./script-with-markers.md" }
|
||||
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#custom-name}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
::use{component="Script"}
|
||||
@@ -0,0 +1,5 @@
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
Whoops, this should have been a test code block
|
||||
@@ -0,0 +1,15 @@
|
||||
# --interactive--
|
||||
|
||||
Testing multiple JavaScript files with unique filekeys.
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
console.log('First JavaScript file');
|
||||
```
|
||||
|
||||
```js
|
||||
console.log('Second JavaScript file');
|
||||
```
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,85 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
solution number two
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
::id{#html-key}
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y3';
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
|
||||
## --text--
|
||||
|
||||
Question 2
|
||||
|
||||
```js
|
||||
var anything = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code` again
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
@@ -0,0 +1,33 @@
|
||||
# --description--
|
||||
|
||||
This is the main description.
|
||||
|
||||
# --instructions--
|
||||
|
||||
These are the main instructions at depth 1.
|
||||
|
||||
```html
|
||||
<div>Main instructions code</div>
|
||||
```
|
||||
|
||||
# --something-else--
|
||||
|
||||
## --instructions--
|
||||
|
||||
These are nested instructions at depth 2 that should be ignored.
|
||||
|
||||
```html
|
||||
<div>Nested instructions code</div>
|
||||
```
|
||||
|
||||
### --instructions--
|
||||
|
||||
These are nested instructions at depth 3 that should also be ignored.
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-all--
|
||||
|
||||
```ts
|
||||
// after all code
|
||||
function teardown() {
|
||||
return 'cleaned up';
|
||||
}
|
||||
teardown();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --after-each--
|
||||
|
||||
```ts
|
||||
// after each code
|
||||
function cleanup() {
|
||||
return 'cleaned up';
|
||||
}
|
||||
cleanup();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-each--
|
||||
|
||||
```ts
|
||||
// before each code
|
||||
function setup() {
|
||||
return 'initialized';
|
||||
}
|
||||
setup();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --before-all--
|
||||
|
||||
```ts
|
||||
// before all code
|
||||
function foo() {
|
||||
return 'bar';
|
||||
}
|
||||
foo();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
Third *hint* with <code>code</code> and `inline code`
|
||||
|
||||
```js
|
||||
// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,36 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio but empty transcript
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio-with-empty-transcript.mp3"
|
||||
},
|
||||
"transcript": []
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
@@ -0,0 +1,42 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with invalid JSON audio
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio.mp3"
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"character": "A",
|
||||
"text": "Hello"
|
||||
}
|
||||
]
|
||||
// missing comma
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
@@ -0,0 +1,39 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio missing filename
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {},
|
||||
"transcript": [
|
||||
{
|
||||
"character": "A",
|
||||
"text": "Hello"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
@@ -0,0 +1,35 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio but no transcript
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio-without-transcript.mp3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
@@ -0,0 +1,29 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio not in JSON code block
|
||||
|
||||
#### --audio--
|
||||
|
||||
Some plain text audio data
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio transcript line missing character
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio.mp3"
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"text": "Hello"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio transcript line missing text
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio.mp3"
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"character": "A"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
@@ -0,0 +1,36 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Question with audio transcript not array
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio.mp3"
|
||||
},
|
||||
"transcript": "not an array"
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Distractor 1
|
||||
|
||||
---
|
||||
|
||||
Distractor 2
|
||||
|
||||
---
|
||||
|
||||
Distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Answer
|
||||
@@ -0,0 +1,107 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 1 with audio timestamps
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio-with-timestamps.mp3",
|
||||
"startTimestamp": 1.5,
|
||||
"finishTimestamp": 3.8
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"character": "Maria",
|
||||
"text": "Hello, how are you?"
|
||||
},
|
||||
{
|
||||
"character": "Tom",
|
||||
"text": "I'm doing well, thank you."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 1, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 1, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 1, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 1, answer
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 2 with audio but no timestamps
|
||||
|
||||
#### --audio--
|
||||
|
||||
```json
|
||||
{
|
||||
"audio": {
|
||||
"filename": "audio-full-file.mp3"
|
||||
},
|
||||
"transcript": [
|
||||
{
|
||||
"character": "Speaker",
|
||||
"text": "This is the full audio transcript."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 2, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 2, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 2, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 2, answer
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 3 without audio
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 3, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 3, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 3, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 3, answer
|
||||
@@ -0,0 +1,93 @@
|
||||
# --quizzes--
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 1
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 1, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 1, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 1, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 1, answer
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 1, question 2
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 1, question 2, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 2, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 1, question 2, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 1, question 2, answer
|
||||
|
||||
## --quiz--
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 2, question 1
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 2, question 1, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 2, question 1, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 2, question 1, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 2, question 1, answer
|
||||
|
||||
### --question--
|
||||
|
||||
#### --text--
|
||||
|
||||
Quiz 2, question 2
|
||||
|
||||
#### --distractors--
|
||||
|
||||
Quiz 2, question 2, distractor 1
|
||||
|
||||
---
|
||||
|
||||
Quiz 2, question 2, distractor 2
|
||||
|
||||
---
|
||||
|
||||
Quiz 2, question 2, distractor 3
|
||||
|
||||
#### --answer--
|
||||
|
||||
Quiz 2, question 2, answer
|
||||
@@ -0,0 +1,24 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#key-for-css}
|
||||
|
||||
::id{#key-for-js}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
::id{#key-for-css}
|
||||
|
||||
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
::id{#key-for-js}
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
::id{#key-for-css}
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#key-for-jsx}
|
||||
|
||||
```jsx
|
||||
var x = 'y';
|
||||
|
||||
/* comment */
|
||||
const Button = () => {
|
||||
return <button> {/* another comment! */} text </button>;
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#key-for-html}
|
||||
@@ -0,0 +1,24 @@
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
::id{#key-for-css}
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
::id{#key-for-js}
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
## --not-allowed--
|
||||
|
||||
should not be allowed
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
### --audio-id--
|
||||
|
||||
answer1-audio
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
### --audio-id--
|
||||
|
||||
answer2-audio
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback line
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
### --feedback--
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
Another paragraph.
|
||||
|
||||
### --feedback--
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
@@ -0,0 +1,43 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
5
|
||||
@@ -0,0 +1,47 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question line 1
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Some inline `code`
|
||||
|
||||
### --feedback--
|
||||
|
||||
That is not correct.
|
||||
|
||||
---
|
||||
|
||||
Some *italics*
|
||||
|
||||
A second answer paragraph.
|
||||
|
||||
---
|
||||
|
||||
<code> code in </code> code tags
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
@@ -0,0 +1,56 @@
|
||||
# --description--
|
||||
|
||||
Paragraph 1
|
||||
|
||||
```html
|
||||
code example
|
||||
```
|
||||
|
||||
```yaml
|
||||
key:
|
||||
- subkey: value
|
||||
anothersubkey: another value
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Paragraph 0
|
||||
|
||||
```html
|
||||
code example 0
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
First hint
|
||||
|
||||
```js
|
||||
// test code
|
||||
```
|
||||
|
||||
Second hint with <code>code</code>
|
||||
|
||||
```js
|
||||
// more test code
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = 'y';
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
id: abc123
|
||||
title: Step 1
|
||||
challengeType: 28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Some description.
|
||||
|
||||
# --hints--
|
||||
```js
|
||||
assert(true);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
```js
|
||||
var x = 1;
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: abc456
|
||||
title: Step 2
|
||||
challengeType: 28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Some description.
|
||||
|
||||
# --hints--
|
||||
```js
|
||||
assert(true);
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
id: abc789
|
||||
title: Step 1
|
||||
challengeType: 28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Some description.
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
```html
|
||||
--fcc-editable-region--
|
||||
<p>First region</p>
|
||||
--fcc-editable-region--
|
||||
<p>Middle</p>
|
||||
--fcc-editable-region--
|
||||
<p>Second region</p>
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
id: step-1
|
||||
title: Step 1
|
||||
challengeType: 28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Placeholder fixture for parser path resolution tests.
|
||||
@@ -0,0 +1,670 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`challenge parser > should import md from other files 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"challengeFiles": [
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "html",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
const element = array[index];
|
||||
// imported from script.md
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "js",
|
||||
"id": "custom-name",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
"description": "<section id="description">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class="language-html">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"instructions": "<section id="instructions">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class="language-html">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": [],
|
||||
"tests": [
|
||||
{
|
||||
"testString": "// test code",
|
||||
"text": "<p>First hint</p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code",
|
||||
"text": "<p>Second hint with <code>code</code></p>",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should not mix other YAML with the frontmatter 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"challengeFiles": [
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "html",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "js",
|
||||
"id": "",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
"description": "<section id="description">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class="language-html">code example
|
||||
</code></pre>
|
||||
<pre><code class="language-yaml">key:
|
||||
- subkey: value
|
||||
anothersubkey: another value
|
||||
</code></pre>
|
||||
</section>",
|
||||
"instructions": "<section id="instructions">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class="language-html">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": [],
|
||||
"tests": [
|
||||
{
|
||||
"testString": "// test code",
|
||||
"text": "<p>First hint</p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code",
|
||||
"text": "<p>Second hint with <code>code</code></p>",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should not parse directives we do not use 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"description": "<section id="description">
|
||||
<p>:root appears, :import appears</p>
|
||||
<p>the next paragraph should appear</p>
|
||||
::import
|
||||
<p>even though it's an import directive, but if we use the full syntax <code>::directive-name{attr="name" attr2="a/path"}</code></p>
|
||||
<p>it goes.</p>
|
||||
<p>::: name [inline-content] {key=val}
|
||||
a container directive
|
||||
:::</p>
|
||||
</section>",
|
||||
"solutions": [],
|
||||
"tests": [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should parse a more realistic md file 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"challengeFiles": [
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Cat Photos</h2>
|
||||
<!-- TODO: Add link to cat photos -->
|
||||
<p>
|
||||
Click here to view more
|
||||
<a target="_blank" href="https://www.freecodecamp.org/cat-photos"
|
||||
>cat photos</a
|
||||
>.
|
||||
</p>
|
||||
<a href="https://www.freecodecamp.org/cat-photos"
|
||||
><img
|
||||
src="https://bit.ly/fcc-relaxing-cat"
|
||||
alt="A cute orange cat lying on its back."
|
||||
/></a>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Cat Lists</h2>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": [
|
||||
19,
|
||||
23,
|
||||
],
|
||||
"ext": "html",
|
||||
"id": "html-key",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}",
|
||||
"editableRegionBoundaries": [
|
||||
7,
|
||||
9,
|
||||
],
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "js",
|
||||
"id": "final-key",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
"description": "<section id="description">
|
||||
<p>When you add a lower rank heading element to the page, it's implied that you're starting a new subsection.</p>
|
||||
<p>After the last <code>h2</code> element of the second <code>section</code> element, add an <code>h3</code> element with the text <code>Things cats love:</code>.</p>
|
||||
<blockquote>
|
||||
<p>Some text in a blockquote</p>
|
||||
<p>
|
||||
Some text in a blockquote, with <code>code</code>
|
||||
</p>
|
||||
</blockquote>
|
||||
</section>",
|
||||
"instructions": "<section id="instructions">
|
||||
<p>Do something with the <code>code</code>.</p>
|
||||
<p>To test that adjacent tags are handled correctly:</p>
|
||||
<p>a bit of <code>code</code> <tag>with more after a space</tag> and another pair of <strong>elements</strong> <em>with a space</em></p>
|
||||
</section>",
|
||||
"solutions": [
|
||||
[
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Cat Photos</h2>
|
||||
<!-- TODO: Add link to cat photos -->
|
||||
<p>
|
||||
Click here to view more
|
||||
<a target="_blank" href="https://www.freecodecamp.org/cat-photos"
|
||||
>cat photos</a
|
||||
>.
|
||||
</p>
|
||||
<a href="https://www.freecodecamp.org/cat-photos"
|
||||
><img
|
||||
src="https://bit.ly/fcc-relaxing-cat"
|
||||
alt="A cute orange cat lying on its back."
|
||||
/></a>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Cat Lists</h2>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"id": "html-key",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}",
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"ext": "js",
|
||||
"id": "final-key",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"testString": "assert(
|
||||
document.querySelectorAll('main > section')[1] &&
|
||||
code.match(/\\<\\/section>/g).length == 2
|
||||
);",
|
||||
"text": "<p>The second <code>section</code> element appears to be missing or does not have both an opening and closing tag.</p>",
|
||||
},
|
||||
{
|
||||
"testString": "assert(
|
||||
document.querySelectorAll('main > section')[1].lastElementChild.nodeName ===
|
||||
'H3'
|
||||
);",
|
||||
"text": "<p>There should be an <code>h3</code> element right above the second <code>section</code> element's closing tag.</p>",
|
||||
},
|
||||
{
|
||||
"testString": "assert(
|
||||
document
|
||||
.querySelectorAll('main > section')[1]
|
||||
.lastElementChild.innerText.toLowerCase()
|
||||
.replace(/\\s+/g, ' ') === 'things cats love:'
|
||||
);",
|
||||
"text": "<p>The <code>h3</code> element right above the second <code>section</code> element's closing tag should have the text <code>Things cats love:</code>. Make sure to include the colon at the end of the text.</p>",
|
||||
},
|
||||
{
|
||||
"testString": "const secondSectionLastElemNode = document.querySelectorAll('main > section')[1]
|
||||
.lastElementChild;
|
||||
assert(
|
||||
secondSectionLastElemNode.nodeName === 'H3' &&
|
||||
secondSectionLastElemNode.previousElementSibling.innerText
|
||||
.toLowerCase()
|
||||
.replace(/\\s+/g, ' ') === 'cat lists'
|
||||
);",
|
||||
"text": "<p>There should be an <code>h2</code> element with the text <code>Cat Lists</code> above the last <code>h3</code> element that is nested in the last <code>section</code> element'. You may have accidentally deleted the <code>h2</code> element.</p>",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should parse a simple md file 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"challengeFiles": [
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "html",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "js",
|
||||
"id": "",
|
||||
"name": "script",
|
||||
},
|
||||
{
|
||||
"contents": "{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020"
|
||||
}
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "json",
|
||||
"id": "",
|
||||
"name": "tsconfig",
|
||||
},
|
||||
],
|
||||
"description": "<section id="description">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class="language-html">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"instructions": "<section id="instructions">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class="language-html">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": [
|
||||
[
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"id": "html-key",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"ext": "js",
|
||||
"id": "",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"testString": "// test code",
|
||||
"text": "<p>First hint</p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code",
|
||||
"text": "<p>Second hint with <code>code</code></p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}",
|
||||
"text": "<p>Third <em>hint</em> with <code>code</code> and <code>inline code</code></p>",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should parse frontmatter 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"challengeFiles": [
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "html",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "js",
|
||||
"id": "",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
"challengeType": 0,
|
||||
"description": "<section id="description">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class="language-html">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"forumTopicId": 18276,
|
||||
"id": "bd7123c8c441eddfaeb5bdef",
|
||||
"isHidden": false,
|
||||
"solutions": [],
|
||||
"tests": [
|
||||
{
|
||||
"testString": "// test code",
|
||||
"text": "<p>First hint</p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code",
|
||||
"text": "<p>Second hint with <code>code</code></p>",
|
||||
},
|
||||
],
|
||||
"title": "Say Hello to HTML Elements",
|
||||
"videoUrl": "https://scrimba.com/p/pVMPUv/cE8Gpt2",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should parse gfm strikethrough and frontmatter 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"challengeFiles": [
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "html",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": [],
|
||||
"ext": "js",
|
||||
"id": "",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
"description": "<section id="description">
|
||||
<p>Paragraph 1 <del>Strikethrough text</del>. https://should.not.be.autolinked</p>
|
||||
<pre><code class="language-html">code example
|
||||
</code></pre>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>example</th>
|
||||
<th>of a</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>gfm</td>
|
||||
<td>table</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>",
|
||||
"instructions": "<section id="instructions">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class="language-html">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": [
|
||||
[
|
||||
{
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"id": "html-key",
|
||||
"name": "index",
|
||||
},
|
||||
{
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"id": "",
|
||||
"name": "styles",
|
||||
},
|
||||
{
|
||||
"contents": "var x = 'y';",
|
||||
"ext": "js",
|
||||
"id": "",
|
||||
"name": "script",
|
||||
},
|
||||
],
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"testString": "// test code",
|
||||
"text": "<p>First hint</p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code",
|
||||
"text": "<p>Second hint with <code>code</code></p>",
|
||||
},
|
||||
{
|
||||
"testString": "// more test code
|
||||
if(let x of xs) {
|
||||
console.log(x);
|
||||
}",
|
||||
"text": "<p>Third <em>hint</em> with <code>code</code> and <code>inline code</code></p>",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should parse md with a scene 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"description": "<section id="description">
|
||||
<p>This challenge has a scene.</p>
|
||||
</section>",
|
||||
"scene": {
|
||||
"commands": [
|
||||
{
|
||||
"character": "Maria",
|
||||
"opacity": 1,
|
||||
"startTime": 0,
|
||||
},
|
||||
{
|
||||
"character": "Maria",
|
||||
"dialogue": {
|
||||
"align": "center",
|
||||
"text": "I'm Maria, the team lead.",
|
||||
},
|
||||
"finishTime": 2.4,
|
||||
"startTime": 0.7,
|
||||
},
|
||||
{
|
||||
"character": "Maria",
|
||||
"opacity": 0,
|
||||
"startTime": 3.4,
|
||||
},
|
||||
],
|
||||
"setup": {
|
||||
"audio": {
|
||||
"filename": "1.1-1.mp3",
|
||||
"finishTimestamp": 4,
|
||||
"startTime": 1,
|
||||
"startTimestamp": 2.6,
|
||||
},
|
||||
"background": "company2-center.png",
|
||||
"characters": [
|
||||
{
|
||||
"character": "Maria",
|
||||
"opacity": 0,
|
||||
"position": {
|
||||
"x": 50,
|
||||
"y": 0,
|
||||
"z": 1.5,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
"solutions": [],
|
||||
"tests": [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`challenge parser > should parse video questions 1`] = `
|
||||
{
|
||||
"assignments": [],
|
||||
"description": "<section id="description">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class="language-html">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"instructions": "<section id="instructions">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class="language-html">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"questions": [
|
||||
{
|
||||
"answers": [
|
||||
{
|
||||
"answer": "<p>Some inline <code>code</code></p>",
|
||||
"audioId": null,
|
||||
"feedback": "<p>That is not correct.</p>",
|
||||
},
|
||||
{
|
||||
"answer": "<p>Some <em>italics</em></p>
|
||||
<p>A second answer paragraph.</p>",
|
||||
"audioId": null,
|
||||
"feedback": null,
|
||||
},
|
||||
{
|
||||
"answer": "<p><code> code in </code> code tags</p>",
|
||||
"audioId": null,
|
||||
"feedback": null,
|
||||
},
|
||||
],
|
||||
"solution": 3,
|
||||
"text": "<p>Question line 1</p>
|
||||
<pre><code class="language-js"> var x = 'y';
|
||||
</code></pre>",
|
||||
},
|
||||
],
|
||||
"solutions": [],
|
||||
"tests": [],
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,66 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
import { parseMD } from '.';
|
||||
|
||||
describe('challenge parser', () => {
|
||||
it('should parse a simple md file', async () => {
|
||||
const parsed = await parseMD(resolve(__dirname, '__fixtures__/simple.md'));
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should parse a more realistic md file', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/realistic.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should import md from other files', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/with-imports.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should parse frontmatter', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/with-frontmatter.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should parse gfm strikethrough and frontmatter', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/with-gfm.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not mix other YAML with the frontmatter', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/with-yaml.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should parse video questions', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/with-video-question.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not parse directives we do not use', async () => {
|
||||
const parsed = await parseMD(
|
||||
resolve(__dirname, '__fixtures__/with-directives.md')
|
||||
);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should parse md with a scene', async () => {
|
||||
const parsed = await parseMD(resolve(__dirname, '__fixtures__/scene.md'));
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// TypeScript declaration file for challenge-parser/parser
|
||||
// This module exports functions to parse challenge markdown files
|
||||
|
||||
type ChallengeFile = {
|
||||
name: string;
|
||||
contents: string;
|
||||
ext: string;
|
||||
editableRegionBoundaries: number[];
|
||||
};
|
||||
export interface ParsedChallenge {
|
||||
id: string;
|
||||
title: string;
|
||||
challengeType: number;
|
||||
description?: string;
|
||||
instructions?: string;
|
||||
questions?: string[];
|
||||
challengeFiles?: ChallengeFile[];
|
||||
solutions?: {
|
||||
contents: string;
|
||||
ext: string;
|
||||
name: string;
|
||||
}[][];
|
||||
[key: string]: unknown; // Allow for additional properties that may be added by plugins
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a markdown challenge file asynchronously
|
||||
* @param filename - Path to the markdown file to parse
|
||||
* @returns Promise that resolves to the parsed challenge data
|
||||
*/
|
||||
export function parseMD(filename: string): Promise<ParsedChallenge>;
|
||||
|
||||
/**
|
||||
* Parses a markdown challenge file synchronously
|
||||
* @param filename - Path to the markdown file to parse
|
||||
* @returns The parsed challenge data
|
||||
*/
|
||||
export function parseMDSync(filename: string): ParsedChallenge;
|
||||
@@ -0,0 +1,97 @@
|
||||
const directive = require('remark-directive');
|
||||
const frontmatter = require('remark-frontmatter');
|
||||
const remark = require('remark-parse');
|
||||
const { readSync } = require('to-vfile');
|
||||
const unified = require('unified');
|
||||
const addFillInTheBlank = require('./plugins/add-fill-in-the-blank');
|
||||
const addFrontmatter = require('./plugins/add-frontmatter');
|
||||
const validateSections = require('./plugins/validate-sections');
|
||||
const addSeed = require('./plugins/add-seed');
|
||||
const addSolution = require('./plugins/add-solution');
|
||||
const addHooks = require('./plugins/add-hooks');
|
||||
const addTests = require('./plugins/add-tests');
|
||||
const addText = require('./plugins/add-text');
|
||||
const addVideoQuestion = require('./plugins/add-video-question');
|
||||
const addAssignment = require('./plugins/add-assignment');
|
||||
const replaceImports = require('./plugins/replace-imports');
|
||||
const restoreDirectives = require('./plugins/restore-directives');
|
||||
const tableAndStrikeThrough = require('./plugins/table-and-strikethrough');
|
||||
const addScene = require('./plugins/add-scene');
|
||||
const addQuizzes = require('./plugins/add-quizzes');
|
||||
const addInteractiveElements = require('./plugins/add-interactive-elements');
|
||||
|
||||
// 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)
|
||||
// validate all section markers before any plugin tries to extract sections
|
||||
.use(validateSections)
|
||||
// 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)
|
||||
// the final five 'add' plugins insert content into file.data
|
||||
// TODO: rename test->hint everywhere? It should make things easier to reason
|
||||
// about.
|
||||
.use(addSeed)
|
||||
.use(addSolution)
|
||||
.use(addInteractiveElements)
|
||||
// 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(addFillInTheBlank)
|
||||
.use(addVideoQuestion)
|
||||
.use(addAssignment)
|
||||
.use(addScene)
|
||||
.use(addQuizzes)
|
||||
.use(addHooks)
|
||||
.use(addTests)
|
||||
.use(addText, [
|
||||
'description',
|
||||
'instructions',
|
||||
'notes',
|
||||
'explanation',
|
||||
'transcript'
|
||||
]);
|
||||
|
||||
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) {
|
||||
if (!err) {
|
||||
resolve(file.data);
|
||||
} else {
|
||||
err.message += ' in file ' + filename;
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.parseMDSync = function parseMDSync(filename) {
|
||||
const file = readSync(filename);
|
||||
const tree = processor.parse(file);
|
||||
try {
|
||||
processor.runSync(tree, file);
|
||||
} catch (err) {
|
||||
err.message += ' in file ' + filename;
|
||||
throw err;
|
||||
}
|
||||
return file.data;
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`process-frontmatter plugin > should have an output to match the snapshot 1`] = `
|
||||
{
|
||||
"challengeType": 0,
|
||||
"forumTopicId": 18276,
|
||||
"id": "bd7123c8c441eddfaeb5bdef",
|
||||
"isHidden": false,
|
||||
"title": "Say Hello to HTML Elements",
|
||||
"videoUrl": "https://scrimba.com/p/pVMPUv/cE8Gpt2",
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,13 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`add-before-hook plugin > should have an output to match the snapshot 1`] = `
|
||||
{
|
||||
"hooks": {
|
||||
"beforeAll": "// before all code
|
||||
function foo() {
|
||||
return 'bar';
|
||||
}
|
||||
foo();",
|
||||
},
|
||||
}
|
||||
`;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user