Generating documentation using factory
This commit is contained in:
@ -51,7 +51,7 @@ Array.prototype.in = function <T>(this: T[], value: T): boolean {
|
|||||||
return this.includes(value);
|
return this.includes(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function loadSamples() {
|
export async function loadSamples() {
|
||||||
// const ds = "https://raw.githubusercontent.com/felixroos/dough-samples/main/";
|
// const ds = "https://raw.githubusercontent.com/felixroos/dough-samples/main/";
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
initAudioOnFirstClick(),
|
initAudioOnFirstClick(),
|
||||||
@ -62,8 +62,6 @@ async function loadSamples() {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSamples();
|
|
||||||
|
|
||||||
export const generateCacheKey = (...args: any[]): string => {
|
export const generateCacheKey = (...args: any[]): string => {
|
||||||
return args.map((arg) => JSON.stringify(arg)).join(",");
|
return args.map((arg) => JSON.stringify(arg)).join(",");
|
||||||
};
|
};
|
||||||
@ -92,6 +90,10 @@ export class UserAPI {
|
|||||||
//this.load = samples("github:tidalcycles/Dirt-Samples/master");
|
//this.load = samples("github:tidalcycles/Dirt-Samples/master");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_all_samples = (): object => {
|
||||||
|
return soundMap.get();
|
||||||
|
};
|
||||||
|
|
||||||
_reportError = (error: any): void => {
|
_reportError = (error: any): void => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
clearTimeout(this.errorTimeoutID);
|
clearTimeout(this.errorTimeoutID);
|
||||||
|
|||||||
@ -1,11 +1,41 @@
|
|||||||
|
import { type Editor } from "./main";
|
||||||
|
|
||||||
const key_shortcut = (shortcut: string): string => {
|
const key_shortcut = (shortcut: string): string => {
|
||||||
return `<kbd class="lg:px-2 lg:py-1.5 px-1 py-1 lg:text-sm text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500">${shortcut}</kbd>`;
|
return `<kbd class="lg:px-2 lg:py-1.5 px-1 py-1 lg:text-sm text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500">${shortcut}</kbd>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const injectAvailableSamples = (): string => {
|
const samples_to_markdown = (samples: object) => {
|
||||||
return "";
|
let markdownList = "";
|
||||||
|
let keys = Object.keys(samples);
|
||||||
|
let i = -1;
|
||||||
|
while (i++ < keys.length - 1) {
|
||||||
|
//@ts-ignore
|
||||||
|
if (!samples[keys[i]].data) continue;
|
||||||
|
//@ts-ignore
|
||||||
|
if (!samples[keys[i]].data.samples) continue;
|
||||||
|
markdownList += `**${keys[i]}** (_${
|
||||||
|
//@ts-ignore
|
||||||
|
samples[keys[i]].data.samples.length
|
||||||
|
}_) `;
|
||||||
|
// let i2 = -1;
|
||||||
|
// while (i2++ < samples[keys[i]].data.samples.length - 1) {
|
||||||
|
// console.log(samples[keys[i]].data.samples[i2]);
|
||||||
|
// markdownList += `\t- <audio controls> <source src="${
|
||||||
|
// samples[keys[i]].data.samples[i2]
|
||||||
|
// }" type="audio/wav">\n
|
||||||
|
// </audio>
|
||||||
|
// `;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return markdownList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const injectAvailableSamples = (application: Editor): string => {
|
||||||
|
let test = samples_to_markdown(application.api._all_samples());
|
||||||
|
return test;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const documentation_factory = (application: Editor) => {
|
||||||
const introduction: string = `
|
const introduction: string = `
|
||||||
# Welcome
|
# Welcome
|
||||||
|
|
||||||
@ -27,7 +57,6 @@ Press ${key_shortcut(
|
|||||||
)} to switch to the global file. This is where everything starts! Evaluate the following script there by pasting and pressing ${key_shortcut(
|
)} to switch to the global file. This is where everything starts! Evaluate the following script there by pasting and pressing ${key_shortcut(
|
||||||
"Ctrl + Enter"
|
"Ctrl + Enter"
|
||||||
)}. You are now making music:
|
)}. You are now making music:
|
||||||
|
|
||||||
<pre><code class="language-javascript">
|
<pre><code class="language-javascript">
|
||||||
bpm(80)
|
bpm(80)
|
||||||
mod(0.25) :: sound('sawtooth')
|
mod(0.25) :: sound('sawtooth')
|
||||||
@ -318,7 +347,6 @@ mod(0.25) && midi(60)
|
|||||||
"Ctrl + Shift + I"
|
"Ctrl + Shift + I"
|
||||||
)} in many web browsers.
|
)} in many web browsers.
|
||||||
- <icode>midi_output(output_name: string)</icode>: Selects the MIDI output to use. You can use the <icode>midi_outputs()</icode> function to get a list of available MIDI outputs first. If the MIDI output is not available, the function will do nothing and keep on with the currently selected MIDI Port.
|
- <icode>midi_output(output_name: string)</icode>: Selects the MIDI output to use. You can use the <icode>midi_outputs()</icode> function to get a list of available MIDI outputs first. If the MIDI output is not available, the function will do nothing and keep on with the currently selected MIDI Port.
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const sound: string = `
|
const sound: string = `
|
||||||
@ -547,9 +575,13 @@ mod(.5)::snd('pad').crush(divseq(2, 16, 8, 4)).clip(.5).out()
|
|||||||
const samples: string = `
|
const samples: string = `
|
||||||
# Audio Samples
|
# Audio Samples
|
||||||
|
|
||||||
|
Audio samples are dynamically loaded from the web. By default, Topos is providing some samples coming from the classic [Dirt-Samples](https://github.com/tidalcycles/Dirt-Samples) but also from the [Topos-Samples](https://github.com/Bubobubobubobubo/Topos-Samples) repository. You can contribute to the latter if you want to share your samples with the community! For each sample folder, we are indicating how many of them are available in parentheses.
|
||||||
|
|
||||||
|
- **sample_folder** (_how_many_)
|
||||||
|
|
||||||
## Available audio samples
|
## Available audio samples
|
||||||
|
|
||||||
${injectAvailableSamples()}
|
${injectAvailableSamples(application)}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -676,8 +708,6 @@ You will often need to use iterators and/or counters to index over data structur
|
|||||||
- <icode>drunk_min(min: number)</icode>: sets the minimum value.
|
- <icode>drunk_min(min: number)</icode>: sets the minimum value.
|
||||||
- <icode>drunk_wrap(wrap: boolean)</icode>: whether to wrap the drunk walk to 0 once the upper limit is reached or not.
|
- <icode>drunk_wrap(wrap: boolean)</icode>: whether to wrap the drunk walk to 0 once the upper limit is reached or not.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
You can control scripts programatically. This is the core concept of Topos after all!
|
You can control scripts programatically. This is the core concept of Topos after all!
|
||||||
@ -769,8 +799,6 @@ Chance operators returning a boolean value are also available:
|
|||||||
|
|
||||||
- <icode>delay(ms: number, func: Function): void</icode>: Delays the execution of a function by a given number of milliseconds.
|
- <icode>delay(ms: number, func: Function): void</icode>: Delays the execution of a function by a given number of milliseconds.
|
||||||
- <icode>delayr(ms: number, nb: number, func: Function): void</icode>: Delays the execution of a function by a given number of milliseconds, repeated a given number of times.
|
- <icode>delayr(ms: number, nb: number, func: Function): void</icode>: Delays the execution of a function by a given number of milliseconds, repeated a given number of times.
|
||||||
|
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const reference: string = `
|
const reference: string = `
|
||||||
@ -814,7 +842,7 @@ Topos is made to be controlled entirely with a keyboard. It is recommanded to st
|
|||||||
- Switch the editor to Vim Mode: ${key_shortcut("Ctrl + V")}.
|
- Switch the editor to Vim Mode: ${key_shortcut("Ctrl + V")}.
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const documentation = {
|
return {
|
||||||
introduction: introduction,
|
introduction: introduction,
|
||||||
interface: software_interface,
|
interface: software_interface,
|
||||||
code: code,
|
code: code,
|
||||||
@ -829,3 +857,4 @@ export const documentation = {
|
|||||||
shortcuts: shortcuts,
|
shortcuts: shortcuts,
|
||||||
about: about,
|
about: about,
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|||||||
18
src/main.ts
18
src/main.ts
@ -14,10 +14,10 @@ import { indentWithTab } from "@codemirror/commands";
|
|||||||
import { vim } from "@replit/codemirror-vim";
|
import { vim } from "@replit/codemirror-vim";
|
||||||
import { AppSettings, Universe } from "./AppSettings";
|
import { AppSettings, Universe } from "./AppSettings";
|
||||||
import { editorSetup } from "./EditorSetup";
|
import { editorSetup } from "./EditorSetup";
|
||||||
import { documentation } from "./Documentation";
|
import { documentation_factory } from "./Documentation";
|
||||||
import { EditorView } from "codemirror";
|
import { EditorView } from "codemirror";
|
||||||
import { Clock } from "./Clock";
|
import { Clock } from "./Clock";
|
||||||
import { UserAPI } from "./API";
|
import { loadSamples, UserAPI } from "./API";
|
||||||
import "./style.css";
|
import "./style.css";
|
||||||
import {
|
import {
|
||||||
Universes,
|
Universes,
|
||||||
@ -27,9 +27,6 @@ import {
|
|||||||
} from "./AppSettings";
|
} from "./AppSettings";
|
||||||
import { tryEvaluate } from "./Evaluator";
|
import { tryEvaluate } from "./Evaluator";
|
||||||
|
|
||||||
type Documentation = { [key: string]: string };
|
|
||||||
const Docs: Documentation = documentation;
|
|
||||||
|
|
||||||
// Importing showdown and setting up the markdown converter
|
// Importing showdown and setting up the markdown converter
|
||||||
import showdown from "showdown";
|
import showdown from "showdown";
|
||||||
showdown.setFlavor("github");
|
showdown.setFlavor("github");
|
||||||
@ -78,6 +75,7 @@ export class Editor {
|
|||||||
userPlugins: Extension[] = [];
|
userPlugins: Extension[] = [];
|
||||||
state: EditorState;
|
state: EditorState;
|
||||||
api: UserAPI;
|
api: UserAPI;
|
||||||
|
docs: { [key: string]: string } = {};
|
||||||
|
|
||||||
// Audio stuff
|
// Audio stuff
|
||||||
audioContext: AudioContext;
|
audioContext: AudioContext;
|
||||||
@ -236,6 +234,13 @@ export class Editor {
|
|||||||
|
|
||||||
let dynamicPlugins = new Compartment();
|
let dynamicPlugins = new Compartment();
|
||||||
|
|
||||||
|
// ================================================================================
|
||||||
|
// Building the documentation
|
||||||
|
loadSamples().then(() => {
|
||||||
|
this.docs = documentation_factory(this);
|
||||||
|
});
|
||||||
|
// ================================================================================
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
// Application event listeners
|
// Application event listeners
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
@ -662,10 +667,11 @@ export class Editor {
|
|||||||
const converter = new showdown.Converter({
|
const converter = new showdown.Converter({
|
||||||
emoji: true,
|
emoji: true,
|
||||||
moreStyling: true,
|
moreStyling: true,
|
||||||
|
backslashEscapesHTMLTags: true,
|
||||||
extensions: [showdownHighlight({ auto_detection: true }), ...bindings],
|
extensions: [showdownHighlight({ auto_detection: true }), ...bindings],
|
||||||
});
|
});
|
||||||
const converted_markdown = converter.makeHtml(
|
const converted_markdown = converter.makeHtml(
|
||||||
Docs[this.currentDocumentationPane]
|
this.docs[this.currentDocumentationPane]
|
||||||
);
|
);
|
||||||
function wrapCodeWithPre(inputString: string): string {
|
function wrapCodeWithPre(inputString: string): string {
|
||||||
let newString = inputString.replace(/<code>/g, "<pre><code>");
|
let newString = inputString.replace(/<code>/g, "<pre><code>");
|
||||||
|
|||||||
Reference in New Issue
Block a user