MDsveX
repository·main·Indexed 25 days ago
https://github.com/pngwn/mdsvexA Markdown preprocessor for Svelte that enables developers to write Markdown as Svelte components. The project includes a monorepo of tools for parsing and manipulating Svelte/Markdown ASTs via the svast specification, including svelte-parse, svast-stringify, and svast-utils. It supports .svx and .svelte.md files, allowing Svelte components to be used within Markdown and vice versa.
What's inside mdsvex
- MDsveX is a Markdown preprocessor for Svelte that allows you to use Markdown syntax directly within Svelte components. It enables a workflow where Markdown files can be treated as Svelte components.
Install and use MDsveX for Svelte components
mainMDsveX is a markdown preprocessor for Svelte components, similar to MDX for React. It enables you to use Svelte components directly within your markdown files, or embed markdown content within your Svelte components. This allows for highly interactive documentation and content pages.
<script> import { Chart } from '../components/Chart.svelte'; </script> # Here’s a chart The chart is rendered inside our MDsveX document. <Chart />Understand the svast Abstract Syntax Tree (AST) architecture
mainsvast (Svelte Abstract Syntax Tree) is an AST implementation that follows the Unist specification.
Key architectural characteristics:
- Unist Compliance: It implements the Unist spec for syntax trees.
- Naming Convention: All node types that implement a unique interface are camelCased and prefixed with
svelte. - Language Agnostic: The AST is designed to be language agnostic and does not impose opinions on the contents of expressions.
- Node Hierarchy: It extends base Unist nodes to provide Svelte-specific syntax support.
Develop a Svelte project
mainAfter creating your project and installing dependencies (using
npm install,pnpm install, oryarn), start the development server using thedevscript. You can use the--openflag to automatically open the application in a new browser tab.npm run dev # or start the server and open the app in a new browser tab npm run dev -- --openInstall svast-utils
mainInstall the
svast-utilspackage via npm to access utilities for working with non-standard svast trees.npm i svast-utilsCreate a new Svelte project with sv
mainUse the
svCLI (powered by@sveltejs/cli) to scaffold a new Svelte project. You can either initialize the project in the current directory or specify a new directory name.# create a new project in the current directory npx sv create # create a new project in my-app npx sv create my-appInstall mdsvex packages via pkg.pr.new
mainYou can install specific versions of mdsvex packages directly from the
pkg.pr.newtool using their unique URLs. This is useful for accessing experimental templates or specific package builds. Available packages includemdsvex,pfm-parse,svast,svast-stringify,svast-utils, andsvelte-parse.npm i https://pkg.pr.new/pngwn/MDsveX/mdsvex@e9631f1 npm i https://pkg.pr.new/pngwn/MDsveX/pfm-parse@e9631f1 npm i https://pkg.pr.new/pngwn/MDsveX/svast@e9631f1 npm i https://pkg.pr.new/pngwn/MDsveX/svast-stringify@e9631f1 npm i https://pkg.pr.new/pngwn/MDsveX/svast-utils@e9631f1 npm i https://pkg.pr.new/pngwn/MDsveX/svelte-parse@e9631f1Build and preview a Svelte project
mainTo prepare your application for production, run thebuildscript. Once the build is complete, you can use thepreviewscript to run a local server that serves the production build for testing.Configure layouts and layoutPropForwarding
mainYou can define layouts for your mdsvex files using the
layoutoption.- Single Layout: Pass a string path to apply one layout to all files.
- Named Layouts: Pass an object where keys are layout names and values are file paths. This enables
layout_mode: 'named'.
Use
layoutPropForwardingto control how props are passed to these layouts:'legacy': Standard Svelte prop forwarding.'runes': Optimized for Svelte 5 runes.
Note: If you use named layouts, you can specify the layout in the file's frontmatter.
Use mdsvex as a Svelte preprocessor
mainIntegrate
mdsvexinto your Svelte project by adding it to yoursvelte.config.jspreprocessors array. This allows you to use.svxfiles (or other extensions) that combine Markdown with Svelte components.Configuration Options
Option Type Default Description extensionstring'.svx'The default extension to use for mdsvex files. extensionsstring[][extension]A list of extensions to treat as mdsvex files. layoutstring | Record<string, string> | falsefalseA single path to a layout file, or an object mapping layout names to file paths. frontmatterobjectundefinedOptions for parsing frontmatter (e.g., type,marker,parse).highlightobject{ highlighter: code_highlight, optimise: true }Syntax highlighting options. smartypantsboolean | objecttrueSmart typography options. remarkPluginsUnifiedPlugins[]Remark plugins to apply to the Markdown AST. rehypePluginsUnifiedPlugins[]Rehype plugins to apply to the HTML AST. layoutPropForwarding'legacy' | 'runes''legacy'Determines how props are forwarded to layouts. Example Usage
import { mdsvex } from 'mdsvex'; /** @type {import('svelte').Config} */ const config = { preprocess: [ mdsvex({ extensions: ['.svx', '.md'], layout: './src/layouts/Post.svelte', remarkPlugins: [], rehypePlugins: [] }) ] }; export default config;Remove positional data with `cleanPositions`
mainThe
cleanPositionsfunction removes allpositiondata from every node in a tree. This is useful for reducing tree size when positional information is no longer required.Key behaviors:
- Mutation: This is a destructive operation. It returns the exact same tree instance passed in, with all
positionproperties deleted.
Signature:
cleanPositions(tree: Node): Node
import { cleanPositions } from 'svast-utils'; const tree = { type: 'root', children: [ { type: 'hello', position: { start: { ... }, end: { ... } } }, { type: 'hello', position: { start: { ... }, end: { ... } } }, { type: 'somethingelse' , children: [ ... ], position: { start: { ... }, end: { ... }} }, ], position: { start: { ... }, end: { ... }} } const clean_tree = cleanPositions(tree); // clean_tree === tree === { // type: 'root', // children: [ // { type: 'hello' }, // { type: 'hello' }, // { // type: 'somethingelse' , // children: [ ... ], // }, // ], // }- Mutation: This is a destructive operation. It returns the exact same tree instance passed in, with all
Walk a svast tree with `walk`
mainThe
walkfunction traverses a svast tree (or a svast-compatible tree), executing a callback for every node visited.Key behaviors:
- Mutation: The operation is not immutable; it returns the exact same tree instance passed in, mutated if necessary.
- Callback Arguments: The callback receives
(node, parent). For the root node,parentisundefined. - Bailing out: Returning
falsefrom the callback preventswalkfrom visiting the children of the current node, but sibling nodes will still be walked. - Recursion: The function uses recursion; extremely large trees may cause stack overflow issues.
Signatures:
walk(tree: Node, cb: walkCallback): NodewalkCallback(node: Node, parent: Node | undefined): void | boolean
import { walk } from 'svast-utils'; const tree = { type: 'root', children: [ { type: 'hello' }, { type: 'hello' }, { type: 'somethingelse' , children: [ ... ]}, ] } const node_names = []; walk(tree, (node, parent) => { node_names.push(node.type); // this will prevent the children of this node from being walked if (node.type === 'somethingelse') return false; }) // node_names === ['root', 'hello', 'hello', 'somethingelse']