Project Syntax
This is the Markdown syntax used to create projects in the curriculum using the default parser.
Markers
# <TITLE>
# <TITLE>
The first paragraph is used as the description of the project. Optionally, a json code block can be used for extra metadata:
Example
Example
# Learn X by Building Y
```json
{
"id": "e5f6a1b2-c3d4-4e5f-1a2b-3c4d5e6f7a8b",
"dashed_name": "learn-x-by-building-y",
"order": 0,
"is_integrated": false,
"tags": ["Coming Soon!"]
}
```
This is a description.
## <N>
## <LESSON_NUMBER>
Zero-based numbering, because of course
meta
## <N>
```json
{
"watch": ["path/relative/to/root"],
"ignore": ["path/relative/to/root"]
}
```
The meta.watch field is used to specify specific files to watch during a lesson. The meta.ignore field is used to specify specific files to ignore during a lesson. The watcher is affected once on lesson load.
The watch and ignore fields are optional. It does not make sense to provide both at the same time.
### --description--
### --description--
<DESCRIPTION_CONTENT>
### --tests--
### --tests--
<TEST_TEXT>
```<LANGUAGE>,runner=<RUNNER>
<TEST_CODE>
```
Available runners: node (for JavaScript/TypeScript) and bash (for shell scripts).
Example
Example
### --tests--
You should ...
```js,runner=node
await new Promise(resolve => setTimeout(resolve, 2000));
assert.equal(true, true);
```
### --seed--
### --seed--
#### --"<FILE_PATH>"--
```<FILE_EXTENSION>
<FILE_CONTENT>
```
#### --cmd--
```bash
<COMMAND>
```
Example
Example
#### --seed--
#### --"index.js"--
```js
// I am an example boilerplate file
```
#### --cmd--
```bash
npm install
```
### --hints--
### --hints--
#### 0
Markdown-valid hint
#### 1
A second Markdown hint with code:
```rust
impl Developer for Camper {
fn can_code(&self) -> bool {
true
}
}
```
Hooks
Hooks can be defined at the lesson level to run code before or after tests.
### --before-all--
Runs once before all tests in the lesson.
### --after-all--
Runs once after all tests in the lesson.
### --before-each--
Runs before each individual test in the lesson.
### --after-each--
Runs after each individual test in the lesson.
Example
Example
### --before-each--
```js,runner=node
const __testVar = 1;
</div>
</details>
### `#### --force--`
Any seed marked with the force flag will overwrite the [`seed_every_lesson` configuration option](configuration.md#definitions-1). Specifically, the force flag causes the seed to run, if it were not going to, and it prevents the seed from running, if it were going to.
```markdown
### --seed--
#### --force--
<!-- Rest of seed -->
## --fcc-end--
An EOF discriminator.
## --fcc-end--
Example
curriculum/locales/english/learn-x-by-building-y.md
curriculum/locales/english/learn-x-by-building-y.md
# Learn X by Building Y
In this course, you will learn X by building y.
## 0
### --description--
Declare a variable `a` with value `1`, in `index.js`.
```javascript
const a = 1;
```
### --tests--
You should declare a variable named `a`.
```js
const test = `console.assert(typeof a);`;
const filePath = 'learn-x-by-building-y/index.js';
const cb = (stdout, stderr) => {
assert.isEmpty(stderr);
assert.exists(stdout);
};
await __helpers.javascriptTest(filePath, test, cb);
```
You should give `a` a value of `1`.
```js
const test = `console.assert(a === 1, \`expected \${a} to equal 1\`);`;
const filePath = 'learn-x-by-building-y/index.js';
const cb = (stdout, stderr) => {
assert.isEmpty(stderr);
assert.exists(stdout);
};
await __helpers.javascriptTest(filePath, test, cb);
```
### --seed--
#### --"index.js"--
```js
// I am an example boilerplate file
```
## 1
```json
{
"watch": ["learn-x-by-building-y/test/index.js"]
}
```
### --description--
Create a new directory named `test`, and create a file `test/index.ts`.
Then add the following:
```ts
const test: string = 'test';
```
### --tests--
You should ...
```js
await new Promise(resolve => setTimeout(resolve, 2000));
assert.equal(true, true);
```
### --seed--
#### --"index.js"--
```javascript
// I am an example boilerplate file
const a = 1;
```
## 2
### --description--
Description.
### --tests--
You should ...
```js
await new Promise(resolve => setTimeout(resolve, 2000));
assert.equal(true, true);
```
### --seed--
#### --cmd--
```bash
echo "I should run first"
```
#### --cmd--
```bash
mkdir test
```
#### --cmd--
```bash
touch test/index.ts
```
#### --"test/index.ts"--
```ts
const test: string = 'test';
```
## 3
### --description--
Description.
### --tests--
You should ...
```js
await new Promise(resolve => setTimeout(resolve, 2000));
assert.equal(true, true);
```
## 4
### --description--
Description.
### --tests--
You should ...
```js
await new Promise(resolve => setTimeout(resolve, 2000));
assert.equal(true, true);
```
## 5
### --description--
Description.
### --tests--
This test will pass after 5 seconds.
```js
await new Promise(resolve => setTimeout(resolve, 5000));
assert.equal(1, 1);
```
## --fcc-end--
It is also possible to add the seed for a lesson in a separate file named <PROJECT_DASHED_NAME>-seed.md within the locales directory.