Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for section directories #162

Merged
merged 14 commits into from
Apr 25, 2024
61 changes: 38 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,49 @@

## Overview

`Gno By Example` is a community-dedicated web app that showcases the fundamentals of Gnolang, the Smart Contract
language
used on [Gno.land](https://gno.land).
`Gno By Example` is a community-dedicated web app that showcases the fundamentals
of Gnolang, the Smart Contract
language used on [Gno.land](https://gno.land).

## Contributing

The base application is built with `React` and utilizes the `Chakra UI` framework. You will need `Node v20+` to run it
locally.
The base application is built with `React` and utilizes the `Chakra UI` framework.
You will need `Node v20+` to run it locally.

Since the project is community-run, users can contribute new tutorials or modify existing ones.
As a community-driven project, users are welcome to contribute by creating new
tutorials or modifying existing ones.

As a community-driven project, users are welcome to contribute by creating new tutorials or modifying existing ones.

All tutorials are located within the `./src/tutorials/gno.land/gbe` subdirectory. Tutorials are automatically generated
All tutorials are located within the
[`./src/tutorials/gno.land/gbe`](./src/tutorials/gno.land/gbe) subdirectory
in their respective section folders. Tutorials are automatically generated
from corresponding `.md` files, with each tutorial having its own subdirectory.

![Banner](.github/assets/contribution-flow.png)

### Generating tutorials

After making modifications to tutorial files (`.md` or other resources), it is necessary to regenerate the global list
of tutorials by running the following command:
After making modifications to tutorial files (`.md` or other resources), it is
necessary to regenerate the global list of tutorials by running the following
command:

```bash
yarn generate
```

This command executes the tutorial route generation script, ensuring that all tutorials are up to date and ready for
dynamic display. Make sure to run this command from the repository root.
This command executes the tutorial route generation script, ensuring that all
tutorials are up-to-date and ready for dynamic display. Make sure to run this
command from the repository root.

### Markdown format

Tutorials can be written using Markdown syntax.

#### Metadata header

A markdown header with some specific metadata is mandatory. This makes it possible for the tutorial generator script to
correctly parse and organize examples.
`title` and `section` values have to be set as part of the metadata at the top of the markdown file:
A markdown header with some specific metadata is mandatory. This makes it
possible for the tutorial generator script to correctly parse and organize examples.
`title` and `section` values have to be set as part of the metadata at the
top of the markdown file:

```md
---
Expand All @@ -51,29 +55,40 @@ section: Example Section
---
```

Note: The `section` field in the metadata header will ultimately decide under
which section the tutorial is generated in.

#### Code snippets

In Gno By Example, there is a special feature that allows referencing entire external files or specific line numbers
from those files, outside of the Markdown files themselves.
In Gno By Example, there is a special feature that allows referencing entire
external files or specific line numbers from those files, outside of the Markdown
files themselves.

To embed the entire content of a specific file inside a code segment, use the following syntax:
To embed the entire content of a specific file inside a code segment, use the
following syntax:

````md
```go file=./myFile.gno
```
````

To embed specific line numbers from an external file inside a code segment, use the following syntax:
To embed specific line numbers from an external file inside a code segment, use
the following syntax:

````md
```go file=./myFile.gno#L1-L2
```
````

The above syntax will embed the content of the first two lines (inclusive) from the `./myFile.gno` file.
The above syntax will embed the content of the first two lines (inclusive) from
the `./myFile.gno` file.

If your sample code relies on another code, you can define the dependencies.
Each dependency code will be shown in a separate tab.
A typical scenario occurs when your sample code is a test file. In order for
your test file to be executable, you need to include the actual implementation
as a dependency.

If your sample code relies on another code, you can define the dependencies. Each dependency code will be shown in a separate tab.
A typical scenario occurs when your sample code is a test file. In order for your test file to be executable, you need to include the actual implementation as a dependency.
To define dependencies, use the following syntax:

````md
Expand Down
37 changes: 26 additions & 11 deletions scripts/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,22 +230,37 @@ const generateTutorialRoutes = async (items: TutorialItem[], outputFile: string)
// Generate the corresponding tutorials in the subdirectories
// and write out the tutorial routes
const generateTutorials = async () => {
const baseDir: string = './src/tutorials/gno.land/gbe';
// const baseDir: string = './scripts/dummy';
const subDirs: string[] = fs.readdirSync(baseDir);
const baseDirPath: string = './src/tutorials/gno.land/gbe';

const sectionDirs: string[] = fs.readdirSync(baseDirPath);
const tutorialItems: TutorialItem[] = [];

for (const subDir of subDirs) {
const subDirPath: string = path.join(baseDir, subDir);
const isDirectory: boolean = fs.statSync(subDirPath).isDirectory();
// Find section subdirs
for (const sectionName of sectionDirs) {
const sectionDirPath: string = path.join(baseDirPath, sectionName);
const isDirectory: boolean = fs.statSync(sectionDirPath).isDirectory();

if (isDirectory) {
// Generate the tutorial for this subdirectory
const item: TutorialItem = await parseTutorial(subDirPath);
// Ignore non-dirs
if (!isDirectory) {
continue
}

tutorialItems.push(item);
console.log(`➡️ Scanning section directory "${sectionName}":`);
const tutorialDirs: string[] = fs.readdirSync(sectionDirPath);
// Find tutorial subdirs in each section
for (const tutorialName of tutorialDirs) {
const tutorialDirPath: string = path.join(sectionDirPath, tutorialName);
const isDirectory: boolean = fs.statSync(tutorialDirPath).isDirectory();

console.log(`✅ Generated tutorial for: ${subDirPath}`);
// Ignore non-dirs
if (!isDirectory) {
continue
}

// Generate the tutorial for this subdirectory
const item: TutorialItem = await parseTutorial(tutorialDirPath);
tutorialItems.push(item);
console.log(`\t ✨ Generated tutorial: ${item.section} - ${tutorialName}`);
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/tutorials.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import helloWorld from "./tutorials/gno.land/gbe/01-hello/index";
import firstApp from "./tutorials/gno.land/gbe/02-count/index";
import primitives from "./tutorials/gno.land/gbe/03-primitives/index";
import variables from "./tutorials/gno.land/gbe/04-variables/index";
import constants from "./tutorials/gno.land/gbe/05-constants/index";
import conditions from "./tutorials/gno.land/gbe/06-conditions/index";
import loops from "./tutorials/gno.land/gbe/07-loops/index";
import helloWorld from "./tutorials/gno.land/gbe/getting-started/01-hello/index";
import firstApp from "./tutorials/gno.land/gbe/getting-started/02-count/index";
import primitives from "./tutorials/gno.land/gbe/getting-started/03-primitives/index";
import variables from "./tutorials/gno.land/gbe/getting-started/04-variables/index";
import constants from "./tutorials/gno.land/gbe/getting-started/05-constants/index";
import conditions from "./tutorials/gno.land/gbe/getting-started/06-conditions/index";
import loops from "./tutorials/gno.land/gbe/getting-started/07-loops/index";

const tutorials = [
{
Expand Down
26 changes: 0 additions & 26 deletions src/tutorials/gno.land/gbe/01-hello/index.ts

This file was deleted.

28 changes: 0 additions & 28 deletions src/tutorials/gno.land/gbe/02-count/index.ts

This file was deleted.

27 changes: 0 additions & 27 deletions src/tutorials/gno.land/gbe/03-primitives/index.ts

This file was deleted.

21 changes: 0 additions & 21 deletions src/tutorials/gno.land/gbe/04-variables/index.ts

This file was deleted.

Loading
Loading