diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs
index 98bc23a7..2af83df9 100644
--- a/packages/core/pattern.mjs
+++ b/packages/core/pattern.mjs
@@ -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()
diff --git a/tutorial/JsDoc.jsx b/tutorial/JsDoc.jsx
new file mode 100644
index 00000000..545052f8
--- /dev/null
+++ b/tutorial/JsDoc.jsx
@@ -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
;
+ }
+ 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}${b ? `#${b}` : ''} `;
+ });
+ return (
+ <>
+ {!!h && {item.longname} }
+
+
+ {item.params?.map((param, i) => (
+
+ {param.name} ({param.type?.names?.join('|')}): {param.description?.replace(/(<([^>]+)>)/gi, '')}
+
+ ))}
+
+
+ {item.examples?.length ? (
+
+ {item.examples?.map((example, k) => (
+
+ ))}
+
+ ) : (
+
+ )}
+ >
+ );
+}
diff --git a/tutorial/Tutorial.jsx b/tutorial/Tutorial.jsx
index 1ec51187..f97b914e 100644
--- a/tutorial/Tutorial.jsx
+++ b/tutorial/Tutorial.jsx
@@ -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';
diff --git a/tutorial/link.svg b/tutorial/link.svg
index 125774e2..b45044c2 100644
--- a/tutorial/link.svg
+++ b/tutorial/link.svg
@@ -1,5 +1,5 @@
-
\ No newline at end of file
diff --git a/tutorial/package-lock.json b/tutorial/package-lock.json
index 42f547fa..de2d597f 100644
--- a/tutorial/package-lock.json
+++ b/tutorial/package-lock.json
@@ -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",
diff --git a/tutorial/package.json b/tutorial/package.json
index cdee3c3a..05e48550 100644
--- a/tutorial/package.json
+++ b/tutorial/package.json
@@ -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",
diff --git a/tutorial/render.js b/tutorial/render.js
deleted file mode 100644
index df88728f..00000000
--- a/tutorial/render.js
+++ /dev/null
@@ -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}${b ? `#${b}` : ''} `;
-})}
-
-${
- item.params
- ?.map(
- (param, i) =>
- `- ${param.name} (${param.type?.names?.join('|')}): ${param.description?.replace(/(<([^>]+)>)/gi, '')}`,
- )
- .join('\n') || ''
-}
-
-${
- item.examples?.length
- ? `
-
- ${item.examples?.map((example, k) => ` `).join('\n\n')}
-
`
- : ''
-}`;
-}
-
-env.addFilter('jsdoc', renderAsMDX);
-
-const rendered = nunjucks.render('tutorial.mdx', { docs });
-console.log(rendered);
diff --git a/tutorial/style.scss b/tutorial/style.scss
index 56b1fa4e..c7b9db9f 100644
--- a/tutorial/style.scss
+++ b/tutorial/style.scss
@@ -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;
diff --git a/tutorial/tutorial.mdx b/tutorial/tutorial.mdx
index 582b1a33..47b41595 100644
--- a/tutorial/tutorial.mdx
+++ b/tutorial/tutorial.mdx
@@ -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 }}
+
-{{ 'Pattern.loopAt' | jsdoc }}
+### Pattern.end
-{{ 'Pattern.chop' | jsdoc }}
+
+
+### Pattern.loopAt
+
+
+
+### Pattern.chop
+
+
## Audio Effects
Wether you're using a synth or a sample, you can apply these effects:
-{{ 'gain' | jsdoc }}
+### gain
-{{ 'velocity' | jsdoc }}
+
-{{ 'cutoff' | jsdoc }}
+### velocity
-{{ 'resonance' | jsdoc }}
+
-{{ 'hcutoff' | jsdoc }}
+### cutoff
-{{ 'hresonance' | jsdoc }}
+
-{{ 'bandf' | jsdoc }}
+### resonance
-{{ 'bandq' | jsdoc }}
+
-{{ 'vowel' | jsdoc }}
+### hcutoff
-{{ 'pan' | jsdoc }}
+
-{{ 'coarse' | jsdoc }}
+### hresonance
-{{ 'shape' | jsdoc }}
+
-{{ 'crush' | jsdoc }}
+### bandf
+
+
+
+### bandq
+
+
+
+### vowel
+
+
+
+### pan
+
+
+
+### coarse
+
+
+
+### shape
+
+
+
+### crush
+
+
@@ -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.
-{{ 'cat' | jsdoc }}
+### cat
-{{ 'seq' | jsdoc }}
+
-{{ 'stack' | jsdoc }}
+### seq
-{{ 'timeCat' | jsdoc }}
+
+
+### stack
+
+
+
+### timeCat
+
+