Skip to content

Commit d1f2d3a

Browse files
authored
Feat/new docs (#446)
* feat: use fumadocs for site * feat: add doc contents * feat: site deploy * fixes * feat: add rhythm patterns * fix: test and build
1 parent 5d78b19 commit d1f2d3a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+6605
-11646
lines changed

package-lock.json

+1,473-2,738
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/.gitignore

+20-12
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1-
# Dependencies
1+
# deps
22
/node_modules
33

4-
# Production
5-
/build
4+
# generated content
5+
.contentlayer
6+
.content-collections
7+
.source
68

7-
# Generated files
8-
.docusaurus
9-
.cache-loader
9+
# test & build
10+
/coverage
11+
/.next/
12+
/out/
13+
/build
14+
*.tsbuildinfo
1015

11-
# Misc
16+
# misc
1217
.DS_Store
13-
.env.local
14-
.env.development.local
15-
.env.test.local
16-
.env.production.local
17-
18+
*.pem
19+
/.pnp
20+
.pnp.js
1821
npm-debug.log*
1922
yarn-debug.log*
2023
yarn-error.log*
24+
25+
# others
26+
.env*.local
27+
.vercel
28+
next-env.d.ts

site/README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# tonal docs
22

3-
```
4-
npm run deploy
3+
Run development server:
4+
5+
```bash
6+
pnpm dev
57
```

site/app/(home)/layout.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { ReactNode } from 'react';
2+
import { HomeLayout } from 'fumadocs-ui/home-layout';
3+
import { baseOptions } from '../layout.config';
4+
5+
export default function Layout({
6+
children,
7+
}: {
8+
children: ReactNode;
9+
}): React.ReactElement {
10+
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
11+
}

site/app/(home)/page.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default function HomePage() {
2+
return (
3+
<main className="flex h-screen flex-col justify-center text-center">
4+
<h1 className="mb-4 text-2xl font-bold">tonal</h1>
5+
<p className="mb-8 text-fd-muted-foreground">A music theory library</p>
6+
</main>
7+
);
8+
}

site/app/docs/[[...slug]]/page.tsx

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { source } from "@/app/source";
2+
import defaultMdxComponents from "fumadocs-ui/mdx";
3+
import {
4+
DocsBody,
5+
DocsDescription,
6+
DocsPage,
7+
DocsTitle,
8+
} from "fumadocs-ui/page";
9+
import type { Metadata } from "next";
10+
import { notFound } from "next/navigation";
11+
12+
export default async function Page({
13+
params,
14+
}: {
15+
params: { slug?: string[] };
16+
}) {
17+
const page = source.getPage(params.slug);
18+
if (!page) notFound();
19+
20+
const MDX = page.data.body;
21+
22+
return (
23+
<DocsPage toc={page.data.toc} full={page.data.full}>
24+
<DocsTitle>{page.data.title}</DocsTitle>
25+
{page.data.package ? (
26+
<div className="flex">
27+
<a
28+
href={`https://www.npmjs.com/package/@tonaljs/${page.data.package}`}
29+
>
30+
<img
31+
className="rounded-lg"
32+
src={`https://img.shields.io/badge/@tonaljs-${page.data.package.replace("-", "--")}-yellow.svg?style=flat-square`}
33+
/>
34+
</a>
35+
</div>
36+
) : null}
37+
<DocsDescription>{page.data.description}</DocsDescription>
38+
<DocsBody>
39+
<MDX components={{ ...defaultMdxComponents }} />
40+
</DocsBody>
41+
</DocsPage>
42+
);
43+
}
44+
45+
export async function generateStaticParams() {
46+
return source.generateParams();
47+
}
48+
49+
export function generateMetadata({ params }: { params: { slug?: string[] } }) {
50+
const page = source.getPage(params.slug);
51+
if (!page) notFound();
52+
53+
return {
54+
title: page.data.title,
55+
description: page.data.description,
56+
} satisfies Metadata;
57+
}

site/app/docs/layout.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { DocsLayout } from 'fumadocs-ui/layout';
2+
import type { ReactNode } from 'react';
3+
import { baseOptions } from '../layout.config';
4+
import { source } from '@/app/source';
5+
6+
export default function Layout({ children }: { children: ReactNode }) {
7+
return (
8+
<DocsLayout tree={source.pageTree} {...baseOptions}>
9+
{children}
10+
</DocsLayout>
11+
);
12+
}

site/app/global.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;

site/app/layout.config.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { type HomeLayoutProps } from "fumadocs-ui/home-layout";
2+
import { BookIcon, GithubIcon } from "lucide-react";
3+
4+
/**
5+
* Shared layout configurations
6+
*
7+
* you can configure layouts individually from:
8+
* Home Layout: app/(home)/layout.tsx
9+
* Docs Layout: app/docs/layout.tsx
10+
*/
11+
export const baseOptions: HomeLayoutProps = {
12+
nav: {
13+
title: "Tonal",
14+
},
15+
links: [
16+
{
17+
text: "Documentation",
18+
icon: <BookIcon />,
19+
url: "/docs",
20+
active: "nested-url",
21+
},
22+
{
23+
text: "Repository",
24+
icon: <GithubIcon />,
25+
url: "https://github.com/tonaljs/tonal",
26+
},
27+
],
28+
};

site/app/layout.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { RootProvider } from "fumadocs-ui/provider";
2+
import { Inter } from "next/font/google";
3+
import type { ReactNode } from "react";
4+
import "./global.css";
5+
6+
const inter = Inter({
7+
subsets: ["latin"],
8+
});
9+
10+
export default function Layout({ children }: { children: ReactNode }) {
11+
return (
12+
<html lang="en" className={inter.className} suppressHydrationWarning>
13+
<body>
14+
<RootProvider search={{ enabled: false }}>{children}</RootProvider>
15+
</body>
16+
</html>
17+
);
18+
}

site/app/source.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { docs, meta } from '@/.source';
2+
import { createMDXSource } from 'fumadocs-mdx';
3+
import { loader } from 'fumadocs-core/source';
4+
5+
export const source = loader({
6+
baseUrl: '/docs',
7+
source: createMDXSource(docs, meta),
8+
});

site/babel.config.js

-3
This file was deleted.

site/blog/authors.yml

-5
This file was deleted.

site/docs/intervals.md site/content/docs/basics/intervals.md

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
---
22
title: Intervals
3-
sidebar_position: 3
3+
description: Calculate and manipulate intervals
4+
package: interval
45
---
56

6-
![tonal](https://img.shields.io/badge/@tonaljs-interval-yellow.svg?style=flat-square) [![npm version](https://img.shields.io/npm/v/@tonaljs/interval.svg?style=flat-square)](https://www.npmjs.com/package/@tonaljs/interval)
7+
`Intervals` module allow to do distance calculations between notes using intervals, obtain information and do calculations:
78

89
```js
910
import { Interval } from "tonal";
1011

12+
Interval.distance("C4", "G4"); // => "5P"
1113
Interval.invert("2M"); // => "7m"
1214
Interval.simplify("9M"); // => "2M"
13-
Interval.semitones("P4"); // => 5
14-
Interval.distance("C4", "G4"); // => "5P"
15+
Interval.semitones("4P"); // => 5
16+
Interval.add("4P", "2M"); // => "5P"
1517
```
1618

1719
## Interval properties
1820

1921
### `Interval.get`
2022

21-
#### `get(name: string) -> Interval`
23+
`get(name: string) -> Interval`
2224

2325
Get properties of an interval:
2426

@@ -49,7 +51,7 @@ Interval.semitones("P4"); // => 5
4951

5052
### `Interval.names`
5153

52-
#### `names() => string[]`
54+
`names() => string[]`
5355

5456
Return a list of (natural) interval names:
5557

@@ -59,7 +61,7 @@ Interval.names(); // => ["1P", "2M", "3M", "4P", "5P", "6m", "7m"]
5961

6062
### `Interval.fromSemitones`
6163

62-
#### `fromSemitones(semitones: number) => string`
64+
`fromSemitones(semitones: number) => string`
6365

6466
Given a number of semitones, returns the interval name:
6567

@@ -74,7 +76,7 @@ Interval.fromSemitones(-7); // => "-5P"
7476

7577
### `Interval.simplify`
7678

77-
#### `simplify(interval: string) => string`
79+
`simplify(interval: string) => string`
7880

7981
Simplify an interval:
8082

@@ -88,7 +90,7 @@ Interval.simplify("-2M"); // => "7m"
8890

8991
### `Interval.invert`
9092

91-
#### `invert(interval: string) => string`
93+
`invert(interval: string) => string`
9294

9395
Get the interval inversion:
9496

@@ -99,7 +101,7 @@ Interval.invert("2M"); // => "7m"
99101

100102
### `Interval.distance`
101103

102-
#### `distance(from: string, to: string) => string`
104+
`distance(from: string, to: string) => string`
103105

104106
Find the interval between two notes.
105107

@@ -109,7 +111,7 @@ Interval.distance("C4", "G4"); // => "5P"
109111

110112
### `Interval.add`
111113

112-
#### `add(a: string, b: string) => string`
114+
`add(a: string, b: string) => string`
113115

114116
Add two intervals:
115117

@@ -119,7 +121,7 @@ Interval.add("3m", "5P"); // => "7m"
119121

120122
### `Interval.subtract`
121123

122-
#### `subtract(min: string, sub: string) => string`
124+
`subtract(min: string, sub: string) => string`
123125

124126
Substract two intervals:
125127

site/content/docs/basics/meta.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"defaultOpen": true,
3+
"pages": ["notes", "intervals", "midi"]
4+
}

site/docs/notation/midi.md site/content/docs/basics/midi.md

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
---
2-
title: MIDI
3-
sidebar_position: 1
2+
title: Midi
3+
description: Manipulate midi notes
4+
package: midi
45
---
56

6-
![tonal](https://img.shields.io/badge/@tonaljs-midi-yellow.svg?style=flat-square) [![npm version](https://img.shields.io/npm/v/@tonaljs/midi.svg?style=flat-square)](https://www.npmjs.com/package/@tonaljs/midi)
7+
```js
8+
import { Midi } from "tonal";
9+
10+
Midi.toMidi("C4"); // => 60
11+
```
712

8-
`@tonaljs/midi` is collection of functions to convert from and to midi numbers
13+
## Functions
914

1015
### `Midi.toMidi`
1116

12-
#### `toMidi(note: string | number) => number | null`
17+
`toMidi(note: string | number) => number | null`
1318

1419
Given a note name or number, return the midi number. Midi numbers are always in range 0..127
1520

@@ -25,7 +30,7 @@ Midi.toMidi(-1); // => null
2530

2631
### `Midi.midiToFreq`
2732

28-
#### `midiToFreq(midi: number, tuning = 440) => number`
33+
`midiToFreq(midi: number, tuning = 440) => number`
2934

3035
Given a midi number, return the frequency:
3136

@@ -39,7 +44,7 @@ Midi.midiToFreq(69, 443); // => 443
3944

4045
### `Midi.midiToNoteName`
4146

42-
#### `midiToNoteName(midi: number) => string`
47+
`midiToNoteName(midi: number) => string`
4348

4449
Given a midi number, returns a note name. The altered notes will have flats unless explicitly set with the optional `useSharps` parameter.
4550

@@ -56,7 +61,7 @@ midiToNoteName(61.7); // => "D4"
5661

5762
### `Midi.freqToMidi`
5863

59-
#### `freqToMidi(freq: number) => number`
64+
`freqToMidi(freq: number) => number`
6065

6166
Given a frequency in hertz, returns the midi number. The midi number can have decimals (with two digits precision)
6267

@@ -70,7 +75,7 @@ Midi.freqToMidi(261); //=> 59.96
7075

7176
### `Midi.pcset`
7277

73-
#### `pcset(set: number[] | string) => number[]`
78+
`pcset(set: number[] | string) => number[]`
7479

7580
Return the pitch class set from a number of midi note numbers or pcset chroma.
7681

@@ -89,7 +94,7 @@ The string is a pitch class chroma, a string with a binary representation of a s
8994

9095
### `Midi.pcsetNearest`
9196

92-
#### `pcsetNearest(set: number[] | string) => (midi: number) => number | undefined`
97+
`pcsetNearest(set: number[] | string) => (midi: number) => number | undefined`
9398

9499
Returns a function that finds the nearest midi note of a pitch class set. Can be used to constrain a note to a scale, for example:
95100

@@ -100,7 +105,7 @@ const nearest = Midi.pcsetNearest(Scale.get("D dorian").chroma);
100105

101106
### `Midi.pcsetSteps`
102107

103-
#### `pcsetSteps(set: number[] | string, tonic: number) => (index: number) => number`
108+
`pcsetSteps(set: number[] | string, tonic: number) => (index: number) => number`
104109

105110
Returns a function to map a pitch class set over any note. Given a tonic a pitch class set, step 0 means the first note, step 1 the second, and so on:
106111

0 commit comments

Comments
 (0)