{output(node.content, state)}
; } } }; var parser = SimpleMarkdown.parserFor(rules); var reactOutput = SimpleMarkdown.outputFor(rules, 'react'); var htmlOutput = SimpleMarkdown.outputFor(rules, 'html'); var blockParseAndOutput = function(source) { // Many rules require content to end in \n\n to be interpreted // as a block. var blockSource = source + "\n\n"; var parseTree = parser(blockSource, {inline: false}); var outputResult = htmlOutput(parseTree); // Or for react output, use: // var outputResult = reactOutput(parseTree); return outputResult; }; ``` ### Response #### Success Response (200) - **outputResult** (string | object) - The rendered markdown content, either as an HTML string or a React-renderable object, depending on the chosen output function. ``` -------------------------------- ### Preview Stories Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Generate live Storybook URLs for visual verification of stories. Use this tool only after completing changes to components and their stories. ```bash preview-stories ``` -------------------------------- ### Auto-format Code with Prettier Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Automatically format the entire project according to Prettier rules. ```bash pnpm prettier . --write ``` -------------------------------- ### Run ESLint Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Execute ESLint to check for code style and potential errors. ```bash pnpm lint ``` -------------------------------- ### Handle New Action in Reducer Source: https://github.com/khan/perseus/blob/main/packages/perseus/src/widgets/interactive-graphs/__docs__/notes/new-graph-type.md Add a new case to the main switch statement in the reducer to handle actions for your new graph type. This example shows handling a `MOVE_VECTOR_SUM_POINT` action. ```typescript case MOVE_VECTOR_SUM_POINT: return doMoveVectorSumPoint(state, action); ``` -------------------------------- ### Creating Parsers and Output Generators Source: https://github.com/khan/perseus/blob/main/packages/simple-markdown/README.md Demonstrates creating a parser and output functions for both React and HTML using a custom set of rules. Note that block-level rules often require content to end with '\n\n'. ```javascript var parser = SimpleMarkdown.parserFor(rules); var reactOutput = SimpleMarkdown.outputFor(rules, 'react')); var htmlOutput = SimpleMarkdown.outputFor(rules, 'html')); ``` -------------------------------- ### Add Default Value to Widget Options Source: https://github.com/khan/perseus/blob/main/packages/perseus-core/src/parse-perseus-json/README.md Example of adding a default value for a 'title' field in widget options using the 'defaulted' function. This is a common pattern for migrating data schemas. ```typescript const parseMyWidgetOptions = object({ // ... title: defaulted(string, () => "Untitled") }); ``` -------------------------------- ### Check Prettier Formatting Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Verify code formatting against Prettier rules without making changes. ```bash pnpm prettier . --check ``` -------------------------------- ### Run Tests Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Execute all tests within the Perseus monorepo. ```bash pnpm test ``` -------------------------------- ### Find Unused Dependencies with Knip Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Use Knip to identify unused files, exports, and dependencies within the project. ```bash pnpm knip ``` -------------------------------- ### Correct Perseus Package Imports Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Demonstrates the recommended import syntax for Perseus packages, adhering to specific ordering and alias usage. Avoid file extensions and cross-package relative imports. ```typescript import React from "react"; // external import {ApiOptions} from "@khanacademy/perseus"; // internal package import {WidgetContainer} from "../widget-container"; // relative import type {WidgetProps} from "@khanacademy/perseus-core"; ``` -------------------------------- ### Perseus Everyday Commands Source: https://github.com/khan/perseus/blob/main/README.md Common commands for development tasks including type checking, testing, linting, and running Storybook. ```bash pnpm tsc -w # run the typechecker in watch mode ``` ```bash pnpm test # run all tests ``` ```bash pnpm lint # find problems ``` ```bash pnpm lint --fix # fix problems ``` ```bash pnpm storybook # open component gallery ``` ```bash pnpm changeset # create a changeset file (see below) ``` ```bash pnpm update-catalog-hashes # update catalog dependency hashes (see below) ``` -------------------------------- ### Test Perseus Editor Package Source: https://github.com/khan/perseus/blob/main/CLAUDE.md Execute tests for the 'perseus-editor' package. ```bash pnpm --filter perseus-editor test ``` -------------------------------- ### Logarithm Graph Data Flow Source: https://github.com/khan/perseus/blob/main/packages/perseus/src/widgets/interactive-graphs/__docs__/notes/logarithm.md Illustrates the data flow for a logarithm graph, from user interaction to state updates and rendering. This outlines the sequence of events and component interactions. ```mermaid graph TD UserInteraction["User interaction (drag/keyboard)"] --> DispatchAction["Dispatch action (movePoint / moveCenter)"] DispatchAction --> Reducer["Reducer applies constraints, updates LogarithmGraphState"] Reducer --> LogarithmGraphComponent["LogarithmGraph component re-renders:"] LogarithmGraphComponent --> ComputeCoefficients["1. Computes coefficients from coords + asymptote (getLogarithmCoefficients)"] LogarithmGraphComponent --> RenderPlot["2. Renders Plot.OfX with domain restriction"] LogarithmGraphComponent --> RenderMovableAsymptote["3. Renders MovableAsymptote with drag handle"] LogarithmGraphComponent --> RenderMovablePoints["4. Renders MovablePoints"] LogarithmGraphComponent --> OnSubmit["On submit: getGradableGraph extracts coords + asymptote"] OnSubmit --> Scoring["Scoring: coefficient comparison via approximateDeepEqual"] ``` -------------------------------- ### KAS Experimenter Input Handling and Display Source: https://github.com/khan/perseus/blob/main/packages/kas/experimenter.html This JavaScript code initializes the KAS Experimenter, setting up event listeners for user input and handling the display of parsed mathematical expressions in multiple formats. It requires the KAS library to be loaded. ```javascript window.onload = function () { var input = document.getElementById("input"); var out = document.getElementById("output"); if ("oninput" in input) { input.addEventListener("input", reprocess, false); } else { input.attachEvent("onkeyup", reprocess); } function addInfo(el, label, value) { el.innerHTML += "" + JSON.stringify(parsed, null, 2) + "", ); addInfo(out, "Compiled", parsed.compile().toString()); }; }; ``` -------------------------------- ### Register Perseus Widgets Source: https://github.com/khan/perseus/blob/main/__docs__/getting-started.mdx Call `init()` once at application startup to register all Perseus widgets. This function is idempotent and handles deprecated widget replacements. ```tsx import {init} from "@khanacademy/perseus"; init(); ``` -------------------------------- ### Inspect Syntax Tree Source: https://github.com/khan/perseus/blob/main/packages/simple-markdown/README.md Log the generated syntax tree to the console for inspection. This helps in understanding the structure produced by the parser. Use JSON.stringify for pretty-printing. ```javascript // pretty-print this with 4-space indentation: console.log(JSON.stringify(syntaxTree, null, 4)); => [ { "content": [ { "content": "Here is a paragraph and an ", "type": "text" }, { "content": [ { "content": "em tag", "type": "text" } ], "type": "em" }, { "content": ".", "type": "text" } ], "type": "paragraph" } ] ``` -------------------------------- ### Parse and Output Markdown with Underlines Source: https://github.com/khan/perseus/blob/main/packages/simple-markdown/README.md Demonstrates parsing a markdown string containing underlines and then outputting the resulting syntax tree as JSON, React elements, and HTML. ```javascript var syntaxTree = parse("__hello underlines__"); console.log(JSON.stringify(syntaxTree, null, 4)); ``` ```json => [ { "content": [ { "content": [ { "content": "hello underlines", "type": "text" } ], "type": "underline" } ], "type": "paragraph" } ] ``` ```javascript reactOutput(syntaxTree) ``` ```javascript => [ { type: 'div', key: null, ref: null, _owner: null, _context: {}, _store: { validated: false, props: [Object] } } ] ``` ```javascript htmlOutput(syntaxTree) ``` ```html => '