Merge pull request #312 from tidalcycles/jsdoc-component

Jsdoc component
This commit is contained in:
Felix Roos 2022-12-19 21:02:21 +01:00 committed by GitHub
commit fc63f4f89c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 270 additions and 209 deletions

View File

@ -676,7 +676,7 @@ export class Pattern {
// Methods without corresponding toplevel functions
/**
* Layers the result of the given function(s). Like {@link superimpose}, but without the original pattern:
* Layers the result of the given function(s). Like {@link Pattern.superimpose}, but without the original pattern:
* @name layer
* @memberof Pattern
* @returns Pattern
@ -1147,7 +1147,7 @@ export function slowcatPrime(...pats) {
/** Concatenation: as with {@link slowcat}, but squashes a cycle from each pattern into one cycle
*
* Synonyms: {@link seq}, {@link sequence}
* Synonyms: {@link Pattern.seq}, {@link Pattern.sequence}
*
* @param {...any} items - The items to concatenate
* @return {Pattern}
@ -1172,7 +1172,7 @@ export function cat(...pats) {
return slowcat(...pats);
}
/** Like {@link seq}, but each step has a length, relative to the whole.
/** Like {@link Pattern.seq}, but each step has a length, relative to the whole.
* @return {Pattern}
* @example
* timeCat([3,e3],[1, g3]).note() // "e3@3 g3".note()

39
tutorial/JsDoc.jsx Normal file
View File

@ -0,0 +1,39 @@
import jsdoc from '../doc.json'; // doc.json is built with `npm run jsdoc-json`
const docs = jsdoc.docs.reduce((acc, obj) => Object.assign(acc, { [obj.longname]: obj }), {});
import { MiniRepl } from './MiniRepl';
export function JsDoc({ name, h = 3 }) {
const item = docs[name];
if (!item) {
console.warn('Not found: ' + name);
return <div />;
}
const CustomHeading = `h${h}`;
const description = item.description.replaceAll(/\{@link ([a-zA-Z\.]+)?#?([a-zA-Z]*)\}/g, (_, a, b) => {
// console.log(_, 'a', a, 'b', b);
return `<a href="#${a.replaceAll('.', '').toLowerCase()}${b ? `-${b}` : ''}">${a}${b ? `#${b}` : ''}</a>`;
});
return (
<>
{!!h && <CustomHeading>{item.longname}</CustomHeading>}
<div dangerouslySetInnerHTML={{ __html: description }} />
<ul>
{item.params?.map((param, i) => (
<li key={i}>
{param.name} ({param.type?.names?.join('|')}): {param.description?.replace(/(<([^>]+)>)/gi, '')}
</li>
))}
</ul>
{item.examples?.length ? (
<div className="space-y-2">
{item.examples?.map((example, k) => (
<MiniRepl tune={example} key={k} />
))}
</div>
) : (
<div />
)}
</>
);
}

View File

@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th
import React from 'react';
import ReactDOM from 'react-dom';
import Tutorial from './tutorial.rendered.mdx';
import Tutorial from './tutorial.mdx';
// import ApiDoc from './ApiDoc';
import './style.scss';
import '@strudel.cycles/react/dist/style.css';

View File

@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">
<path fill-rule="evenodd"
<path fill-rule="evenodd" fill="white"
d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z">
</path>
</svg>

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 535 B

View File

@ -21,7 +21,6 @@
"autoprefixer": "^10.4.7",
"install": "^0.13.0",
"npm": "^8.10.0",
"nunjucks": "^3.2.3",
"postcss": "^8.4.13",
"rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.0.1",
@ -796,12 +795,6 @@
"semver": "bin/semver.js"
}
},
"node_modules/a-sync-waterfall": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
"integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",
"dev": true
},
"node_modules/acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@ -865,12 +858,6 @@
"integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==",
"dev": true
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true
},
"node_modules/autoprefixer": {
"version": "10.4.7",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
@ -1159,15 +1146,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
"dev": true,
"engines": {
"node": ">= 6"
}
},
"node_modules/convert-source-map": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
@ -4847,31 +4825,6 @@
"inBundle": true,
"license": "ISC"
},
"node_modules/nunjucks": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz",
"integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==",
"dev": true,
"dependencies": {
"a-sync-waterfall": "^1.0.0",
"asap": "^2.0.3",
"commander": "^5.1.0"
},
"bin": {
"nunjucks-precompile": "bin/precompile"
},
"engines": {
"node": ">= 6.9.0"
},
"peerDependencies": {
"chokidar": "^3.3.0"
},
"peerDependenciesMeta": {
"chokidar": {
"optional": true
}
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -7039,12 +6992,6 @@
}
}
},
"a-sync-waterfall": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
"integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",
"dev": true
},
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@ -7093,12 +7040,6 @@
"integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==",
"dev": true
},
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true
},
"autoprefixer": {
"version": "10.4.7",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
@ -7283,12 +7224,6 @@
"integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
"dev": true
},
"commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
"dev": true
},
"convert-source-map": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
@ -9805,17 +9740,6 @@
}
}
},
"nunjucks": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz",
"integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==",
"dev": true,
"requires": {
"a-sync-waterfall": "^1.0.0",
"asap": "^2.0.3",
"commander": "^5.1.0"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",

View File

@ -8,7 +8,7 @@
"build": "npm run render && vite build",
"preview": "vite preview",
"jsdoc-json": "jsdoc ../packages/ --template ../node_modules/jsdoc-json --destination ../doc.json -c ../jsdoc.config.json",
"render": "npm run jsdoc-json && node ./render.js > tutorial.rendered.mdx"
"render": "npm run jsdoc-json"
},
"type": "module",
"dependencies": {
@ -25,7 +25,6 @@
"autoprefixer": "^10.4.7",
"install": "^0.13.0",
"npm": "^8.10.0",
"nunjucks": "^3.2.3",
"postcss": "^8.4.13",
"rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.0.1",

View File

@ -1,48 +0,0 @@
import nunjucks from 'nunjucks';
import { readFile } from 'node:fs/promises';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __dirname = dirname(fileURLToPath(import.meta.url));
const jsdoc = JSON.parse(await readFile(`${__dirname}/../doc.json`, 'utf8'));
// import jsdoc from '../doc.json' assert { type: 'json' }; // node 18
const env = nunjucks.configure('.', { autoescape: false });
const docs = jsdoc.docs.reduce((acc, obj) => Object.assign(acc, { [obj.longname]: obj }), {});
function renderAsMDX(name) {
const item = docs[name];
if (!item) {
console.warn('Not found: ' + name);
return '';
}
return `### ${item.longname}
${item.description.replaceAll(/\{@link ([a-zA-Z]+)?#?([a-zA-Z]*)\}/g, (_, a, b) => {
// console.log(_, 'a', a, 'b', b);
return `<a href="#${a}${b ? `-${b}` : ''}">${a}${b ? `#${b}` : ''}</a>`;
})}
${
item.params
?.map(
(param, i) =>
`- ${param.name} (${param.type?.names?.join('|')}): ${param.description?.replace(/(<([^>]+)>)/gi, '')}`,
)
.join('\n') || ''
}
${
item.examples?.length
? `
<div className="space-y-2">
${item.examples?.map((example, k) => `<MiniRepl tune={\`${example}\`} />`).join('\n\n')}
</div>`
: ''
}`;
}
env.addFilter('jsdoc', renderAsMDX);
const rendered = nunjucks.render('tutorial.mdx', { docs });
console.log(rendered);

View File

@ -33,8 +33,6 @@ h6:hover .icon-link,
width: 16px;
height: 16px;
display: block;
color: gray;
fill: black;
position: absolute;
visibility: hidden;
margin-left: -20px;

View File

@ -1,4 +1,5 @@
import { MiniRepl } from './MiniRepl';
import { JsDoc } from './JsDoc';
# Table of Contents
@ -407,43 +408,77 @@ The sampler will always pick the closest matching sample for the current note!
## Sampler Effects
{{ 'Pattern.begin' | jsdoc }}
### Pattern.begin
{{ 'Pattern.end' | jsdoc }}
<JsDoc name="Pattern.begin" h={0} />
{{ 'Pattern.loopAt' | jsdoc }}
### Pattern.end
{{ 'Pattern.chop' | jsdoc }}
<JsDoc name="Pattern.end" h={0} />
### Pattern.loopAt
<JsDoc name="Pattern.loopAt" h={0} />
### Pattern.chop
<JsDoc name="Pattern.chop" h={0} />
## Audio Effects
Wether you're using a synth or a sample, you can apply these effects:
{{ 'gain' | jsdoc }}
### gain
{{ 'velocity' | jsdoc }}
<JsDoc name="gain" h={0} />
{{ 'cutoff' | jsdoc }}
### velocity
{{ 'resonance' | jsdoc }}
<JsDoc name="velocity" h={0} />
{{ 'hcutoff' | jsdoc }}
### cutoff
{{ 'hresonance' | jsdoc }}
<JsDoc name="cutoff" h={0} />
{{ 'bandf' | jsdoc }}
### resonance
{{ 'bandq' | jsdoc }}
<JsDoc name="resonance" h={0} />
{{ 'vowel' | jsdoc }}
### hcutoff
{{ 'pan' | jsdoc }}
<JsDoc name="hcutoff" h={0} />
{{ 'coarse' | jsdoc }}
### hresonance
{{ 'shape' | jsdoc }}
<JsDoc name="hresonance" h={0} />
{{ 'crush' | jsdoc }}
### bandf
<JsDoc name="bandf" h={0} />
### bandq
<JsDoc name="bandq" h={0} />
### vowel
<JsDoc name="vowel" h={0} />
### pan
<JsDoc name="pan" h={0} />
### coarse
<JsDoc name="coarse" h={0} />
### shape
<JsDoc name="shape" h={0} />
### crush
<JsDoc name="crush" h={0} />
<br />
@ -508,18 +543,28 @@ You can use this with any function that declares a type (like `n`, `s`, `note`,
The following functions will return a pattern.
<!--
{{ 'pure' | jsdoc }}
### pure
<JsDoc name="pure" h={0} />
Most of the time, you won't need that function as input values of pattern creating functions are purified by default.
-->
{{ 'cat' | jsdoc }}
### cat
{{ 'seq' | jsdoc }}
<JsDoc name="cat" h={0} />
{{ 'stack' | jsdoc }}
### seq
{{ 'timeCat' | jsdoc }}
<JsDoc name="seq" h={0} />
### stack
<JsDoc name="stack" h={0} />
### timeCat
<JsDoc name="timeCat" h={0} />
<!-- ## polymeter
@ -580,132 +625,234 @@ When using JS patterns, there is a lot more you can do.
The following functions modify a pattern temporal structure in some way.
{{ 'Pattern.slow' | jsdoc }}
### Pattern.slow
{{ 'Pattern.fast' | jsdoc }}
<JsDoc name="Pattern.slow" h={0} />
{{ 'Pattern.early' | jsdoc }}
### Pattern.fast
{{ 'Pattern.late' | jsdoc }}
<JsDoc name="Pattern.fast" h={0} />
{{ 'Pattern.legato' | jsdoc }}
### Pattern.early
{{ 'Pattern.struct' | jsdoc }}
<JsDoc name="Pattern.early" h={0} />
{{ 'Pattern.euclid' | jsdoc }}
### Pattern.late
{{ 'Pattern.euclidLegato' | jsdoc }}
<JsDoc name="Pattern.late" h={0} />
{{ 'Pattern.rev' | jsdoc }}
### Pattern.legato
{{ 'Pattern.iter' | jsdoc }}
<JsDoc name="Pattern.legato" h={0} />
{{ 'Pattern.iterBack' | jsdoc }}
### Pattern.struct
<JsDoc name="Pattern.struct" h={0} />
### Pattern.euclid
<JsDoc name="Pattern.euclid" h={0} />
### Pattern.euclidLegato
<JsDoc name="Pattern.euclidLegato" h={0} />
### Pattern.rev
<JsDoc name="Pattern.rev" h={0} />
### Pattern.iter
<JsDoc name="Pattern.iter" h={0} />
### Pattern.iterBack
<JsDoc name="Pattern.iterBack" h={0} />
## Conditional Modifiers
{{ 'Pattern.every' | jsdoc }}
### Pattern.every
{{ 'Pattern.each' | jsdoc }}
<JsDoc name="Pattern.every" h={0} />
{{ 'Pattern.when' | jsdoc }}
### Pattern.when
<JsDoc name="Pattern.when" h={0} />
## Accumulation Modifiers
{{ 'Pattern.stack' | jsdoc }}
### Pattern.stack
{{ 'Pattern.superimpose' | jsdoc }}
<JsDoc name="Pattern.stack" h={0} />
{{ 'Pattern.layer' | jsdoc }}
### Pattern.superimpose
{{ 'Pattern.off' | jsdoc }}
<JsDoc name="Pattern.superimpose" h={0} />
{{ 'Pattern.echo' | jsdoc }}
### Pattern.layer
{{ 'Pattern.echoWith' | jsdoc }}
<JsDoc name="Pattern.layer" h={0} />
### Pattern.off
<JsDoc name="Pattern.off" h={0} />
### Pattern.echo
<JsDoc name="Pattern.echo" h={0} />
### Pattern.echoWith
<JsDoc name="Pattern.echoWith" h={0} />
## Concat Modifiers
{{ 'Pattern.seq' | jsdoc }}
### Pattern.seq
{{ 'Pattern.cat' | jsdoc }}
<JsDoc name="Pattern.seq" h={0} />
### Pattern.cat
<JsDoc name="Pattern.cat" h={0} />
## Value Modifiers
{{ 'Pattern.add' | jsdoc }}
### Pattern.add
{{ 'Pattern.sub' | jsdoc }}
<JsDoc name="Pattern.add" h={0} />
{{ 'Pattern.mul' | jsdoc }}
### Pattern.sub
{{ 'Pattern.div' | jsdoc }}
<JsDoc name="Pattern.sub" h={0} />
{{ 'Pattern.round' | jsdoc }}
### Pattern.mul
{{ 'Pattern.apply' | jsdoc }}
<JsDoc name="Pattern.mul" h={0} />
{{ 'Pattern.range' | jsdoc }}
### Pattern.div
{{ 'Pattern.chunk' | jsdoc }}
<JsDoc name="Pattern.div" h={0} />
{{ 'Pattern.chunkBack' | jsdoc }}
### Pattern.round
<JsDoc name="Pattern.round" h={0} />
### Pattern.apply
<JsDoc name="Pattern.apply" h={0} />
### Pattern.range
<JsDoc name="Pattern.range" h={0} />
### Pattern.chunk
<JsDoc name="Pattern.chunk" h={0} />
### Pattern.chunkBack
<JsDoc name="Pattern.chunkBack" h={0} />
## Continuous Signals
Signals are patterns with continuous values, meaning they have theoretically infinite steps.
They can provide streams of numbers that can be sampled at discrete points in time.
{{ 'saw' | jsdoc }}
### saw
{{ 'sine' | jsdoc }}
<JsDoc name="saw" h={0} />
{{ 'cosine' | jsdoc }}
### sine
{{ 'tri' | jsdoc }}
<JsDoc name="sine" h={0} />
{{ 'square' | jsdoc }}
### cosine
<JsDoc name="cosine" h={0} />
### tri
<JsDoc name="tri" h={0} />
### square
<JsDoc name="square" h={0} />
### Ranges from -1 to 1
There is also `saw2`, `sine2`, `cosine2`, `tri2` and `square2` which have a range from -1 to 1!
{{ 'rand' | jsdoc }}
### rand
{{ 'perlin' | jsdoc }}
<JsDoc name="rand" h={0} />
{{ 'irand' | jsdoc }}
### perlin
<JsDoc name="perlin" h={0} />
### irand
<JsDoc name="irand" h={0} />
## Random Modifiers
These methods add random behavior to your Patterns.
{{ 'chooseCycles' | jsdoc }}
### chooseCycles
{{ 'Pattern.degradeBy' | jsdoc }}
<JsDoc name="chooseCycles" h={0} />
{{ 'Pattern.degrade' | jsdoc }}
### Pattern.degradeBy
{{ 'Pattern.undegradeBy' | jsdoc }}
<JsDoc name="Pattern.degradeBy" h={0} />
{{ 'Pattern.sometimesBy' | jsdoc }}
### Pattern.degrade
{{ 'Pattern.sometimes' | jsdoc }}
<JsDoc name="Pattern.degrade" h={0} />
{{ 'Pattern.someCyclesBy' | jsdoc }}
### Pattern.undegradeBy
{{ 'Pattern.someCycles' | jsdoc }}
<JsDoc name="Pattern.undegradeBy" h={0} />
{{ 'Pattern.often' | jsdoc }}
### Pattern.sometimesBy
{{ 'Pattern.rarely' | jsdoc }}
<JsDoc name="Pattern.sometimesBy" h={0} />
{{ 'Pattern.almostNever' | jsdoc }}
### Pattern.sometimes
{{ 'Pattern.almostAlways' | jsdoc }}
<JsDoc name="Pattern.sometimes" h={0} />
{{ 'Pattern.never' | jsdoc }}
### Pattern.someCyclesBy
{{ 'Pattern.always' | jsdoc }}
<JsDoc name="Pattern.someCyclesBy" h={0} />
### Pattern.someCycles
<JsDoc name="Pattern.someCycles" h={0} />
### Pattern.often
<JsDoc name="Pattern.often" h={0} />
### Pattern.rarely
<JsDoc name="Pattern.rarely" h={0} />
### Pattern.almostNever
<JsDoc name="Pattern.almostNever" h={0} />
### Pattern.almostAlways
<JsDoc name="Pattern.almostAlways" h={0} />
### Pattern.never
<JsDoc name="Pattern.never" h={0} />
### Pattern.always
<JsDoc name="Pattern.always" h={0} />
<br />
<br />
@ -822,7 +969,9 @@ Now you're all set!
If you now hear sound, congratulations! If not, you can get help on the [#strudel channel in the TidalCycles discord](https://discord.com/invite/HGEdXmRkzT).
{{ 'Pattern.osc' | jsdoc }}
### Pattern.osc
<JsDoc name="Pattern.osc" h={0} />
## Superdirt Params