import { Editor } from "../main"; import { introduction, atelier, software_interface, shortcuts, code, mouse, interaction } from "./basics"; import { amplitude, effects, sampler, synths, filters, audio_basics } from "./learning/audio_engine"; import { lfos, functions, generators, variables, probabilities } from './patterns'; import { ziffers_basics, ziffers_scales, ziffers_rhythm, ziffers_algorithmic, ziffers_tonnetz, ziffers_syncing } from "./patterns/ziffers"; import { loading_samples } from "./learning/samples/loading_samples"; import { sample_banks } from "./learning/samples/sample_banks"; import { sample_list } from "./learning/samples/sample_list"; import { oscilloscope } from "./more/oscilloscope"; import { synchronisation } from "./more/synchronisation"; import { about } from "./more/about"; import { bonus } from "./more/bonus"; import { visualization } from "./more/visualization"; import { chaining } from "./patterns/chaining"; import { time } from "./learning/time/time"; import { linear_time } from "./learning/time/linear_time"; import { cyclical_time } from "./learning/time/cyclical_time"; import { long_forms } from "./learning/time/long_forms"; import { midi } from "./learning/midi"; import { osc } from "./learning/osc"; import { patterns } from "./patterns/patterns"; // Setting up the Markdown converter with syntax highlighting import showdown from "showdown"; import showdownHighlight from "showdown-highlight"; import "highlight.js/styles/atom-one-dark-reasonable.min.css"; import { createDocumentationStyle } from "../DOM/DomElements"; showdown.setFlavor("github"); type StyleBinding = { type: string; regex: RegExp; replace: (match: string, p1: string) => string; }; export const key_shortcut = (shortcut: string): string => { return `${shortcut}`; }; export const makeExampleFactory = (application: Editor): Function => { const make_example = ( description: string, code: string, open: boolean = false, ) => { const codeId = `codeExample${application.exampleCounter++}`; // Store the code snippet in the data structure application.api.codeExamples[codeId] = code; return `
${description}
${code.trim()}
`; }; return make_example; }; export const documentation_pages = [ "introduction", "atelier", "sampler", "amplitude", "audio_basics", "filters", "effects", "interface", "interaction", "code", "time", "linear", "cyclic", "longform", "synths", "chaining", "patterns", "ziffers_basics", "ziffers_scales", "ziffers_rhythm", "ziffers_algorithmic", "ziffers_tonnetz", "ziffers_syncing", "midi", "osc", "functions", "generators", "lfos", "probabilities", "variables", "synchronisation", "mouse", "shortcuts", "about", "bonus", "oscilloscope", "sample_list", "loading_samples", "visualization" ]; export const documentation_factory = (application: Editor) => { /** * Creates the documentation for the given application. * @param application The editor application. * @returns An object containing various documentation sections. */ application.api.codeExamples = {}; return { introduction: introduction(application), atelier: atelier(application), interface: software_interface(application), interaction: interaction(application), code: code(application), time: time(application), linear: linear_time(application), cyclic: cyclical_time(application), longform: long_forms(application), synths: synths(application), filters: filters(application), chaining: chaining(application), patterns: patterns(application), ziffers_basics: ziffers_basics(application), ziffers_scales: ziffers_scales(application), ziffers_algorithmic: ziffers_algorithmic(application), ziffers_rhythm: ziffers_rhythm(application), ziffers_tonnetz: ziffers_tonnetz(application), ziffers_syncing: ziffers_syncing(application), midi: midi(application), osc: osc(application), lfos: lfos(application), variables: variables(application), probabilities: probabilities(application), functions: functions(application), generators: generators(application), shortcuts: shortcuts(application), amplitude: amplitude(application), effects: effects(application), sampler: sampler(application), mouse: mouse(application), oscilloscope: oscilloscope(application), audio_basics: audio_basics(application), synchronisation: synchronisation(application), bonus: bonus(application), visualization: visualization(application), sample_list: sample_list(application), sample_banks: sample_banks(application), loading_samples: loading_samples(application), about: about(), }; }; export const showDocumentation = (app: Editor): void => { const toggleElementVisibility = (elementId: string, shouldHide: boolean): void => { const element = document.getElementById(elementId); if (element) { element.classList.toggle("hidden", shouldHide); } }; const applyStyleBindings = (style: Record, updateContent: (bindings: StyleBinding[]) => void): void => { const bindings: StyleBinding[] = Object.keys(style).map((key) => ({ type: "output", regex: new RegExp(`<${key}([^>]*)>`, "g"), replace: (_, p1) => `<${key} class="${style[key]}" ${p1}>` })); updateContent(bindings); }; const appHidden = document.getElementById("app")?.classList.contains("hidden"); if (appHidden) { toggleElementVisibility("app", false); toggleElementVisibility("documentation", true); app.exampleIsPlaying = false; } else { toggleElementVisibility("app", true); toggleElementVisibility("documentation", false); const style = createDocumentationStyle(app); applyStyleBindings(style, (bindings: StyleBinding[]) => updateDocumentationContent(app, bindings)); } // Reset the URL to the base URL window.history.pushState({}, '', '/'); }; // export const showDocumentation = (app: Editor) => { // /** // * Shows or hides the documentation based on the current state of the app. // * @param app - The Editor instance. // */ // if (document.getElementById("app")?.classList.contains("hidden")) { // document.getElementById("app")?.classList.remove("hidden"); // document.getElementById("documentation")?.classList.add("hidden"); // app.exampleIsPlaying = false; // } else { // document.getElementById("app")?.classList.add("hidden"); // document.getElementById("documentation")?.classList.remove("hidden"); // // Load and convert Markdown content from the documentation file // let style = createDocumentationStyle(app); // function update_and_assign(callback: Function) { // let bindings = Object.keys(style).map((key) => ({ // type: "output", // regex: new RegExp(`<${key}([^>]*)>`, "g"), // //@ts-ignore // replace: (match, p1) => `<${key} class="${style[key]}" ${p1}>`, // })); // callback(bindings) // } // update_and_assign((e: Object) => updateDocumentationContent(app, e)); // } // }; export const hideDocumentation = () => { /** * Hides the documentation section and shows the main application. */ if (document.getElementById("app")?.classList.contains("hidden")) { document.getElementById("app")?.classList.remove("hidden"); document.getElementById("documentation")?.classList.add("hidden"); } }; export const updateDocumentationContent = (app: Editor, bindings: any) => { /** * Updates the content of the documentation pane with the converted markdown. * * @param app - The editor application. * @param bindings - Additional bindings for the showdown converter. */ let loading_message: string = "

Loading! Clic to refresh!

"; const converter = new showdown.Converter({ emoji: true, moreStyling: true, backslashEscapesHTMLTags: true, extensions: [showdownHighlight({ pre: true, auto_detection: false }), ...bindings], }); if (Object.keys(app.docs).length === 0) { app.docs = documentation_factory(app); } function _update_and_assign(callback: Function) { const converted_markdown = converter.makeHtml( app.docs[app.currentDocumentationPane], ); callback(converted_markdown) } _update_and_assign((e: string) => { let display_content = e === undefined ? loading_message : e; document.getElementById("documentation-content")!.innerHTML = display_content; }) if (document.getElementById("documentation-content")!.innerHTML.replace(/"/g, "'") == loading_message.replace(/"/g, "'")) { setTimeout(() => { updateDocumentationContent(app, bindings); }, 100); } }